复习:
把第三方的类库交给IOC来管理,这个时候就没办法用注解的方式 因为我们的jar里面发的都是callss文件,字节码文件 我们看到的结果也是idea反编译的结果 这个文件是只读 是无法进行修改的 所以只能用xml 没办法用到注解
像我们自己创建的类 就可以用注解+扫描的方式来处理
新课:
2 .导入依赖
jar junit junit 4.12 test
com.atguigu.spring.proxy.Calculator
- package com.atguigu.spring.proxy;
-
- public interface Calculator {
-
- int add(int i, int j);
- int sub(int i, int j);
- int mul(int i, int j);
- int div(int i, int j);
-
- }
第二步 创建实现类 CalculatorImpl 实现implements Calculator 并重写里面的方法
- package com.atguigu.spring.proxy;
-
- public class CalculatorImpl implements Calculator{
- @Override
- public int add(int i, int j) {
- System.out.println("[日志] add 方法开始了,参数是:" + i + "," + j);
- int result = i + j;
- System.out.println("方法内部 result = " + result);
- System.out.println("[日志] add 方法结束了,结果是:" + result);
- return result;
-
- }
-
- @Override
- public int sub(int i, int j) {
- System.out.println("[日志] sub 方法开始了,参数是:" + i + "," + j);
- int result = i - j;
- System.out.println("方法内部 result = " + result);
- System.out.println("[日志] sub 方法结束了,结果是:" + result);
- return result;
- }
-
- @Override
- public int mul(int i, int j) {
- System.out.println("[日志] mul 方法开始了,参数是:" + i + "," + j);
- int result = i * j;
- System.out.println("方法内部 result = " + result);
- System.out.println("[日志] mul 方法结束了,结果是:" + result);
- return result;
- }
-
- @Override
- public int div(int i, int j) {
- System.out.println("[日志] div 方法开始了,参数是:" + i + "," + j);
- int result = i / j;
- System.out.println("方法内部 result = " + result);
- System.out.println("[日志] div 方法结束了,结果是:" + result);
- return result;
- }
- }
提出问题
- package com.atguigu.spring.proxy;
-
- /**
- * Date:2022/7/4
- * Author:ybc
- * Description:
- */
- public class CalculatorStaticProxy implements Calculator {
-
- private CalculatorImpl target;
-
- public CalculatorStaticProxy(CalculatorImpl target) {
- this.target = target;
- }
-
- @Override
- public int add(int i, int j) {
- System.out.println("日志,方法:add,参数:"+i+","+j);
- int result = target.add(i, j);
- System.out.println("日志,方法:add,结果:"+result);
- return result;
- }
-
- @Override
- public int sub(int i, int j) {
- System.out.println("日志,方法:sub,参数:"+i+","+j);
- int result = target.sub(i, j);
- System.out.println("日志,方法:sub,结果:"+result);
- return result;
- }
-
- @Override
- public int mul(int i, int j) {
- System.out.println("日志,方法:mul,参数:"+i+","+j);
- int result = target.mul(i, j);
- System.out.println("日志,方法:mul,结果:"+result);
- return result;
- }
-
- @Override
- public int div(int i, int j) {
- System.out.println("日志,方法:div,参数:"+i+","+j);
- int result = target.div(i, j);
- System.out.println("日志,方法:div,结果:"+result);
- return result;
- }
- }
核心业务类 内部方法 目标方法 目标对象 CalculatorImpl
- package com.atguigu.spring.proxy;
-
- /**
- * Date:2022/7/4
- * Author:ybc
- * Description:
- */
- public class CalculatorImpl implements Calculator {
- @Override
- public int add(int i, int j) {
- int result = i + j;
- System.out.println("方法内部,result:"+result);
- return result;
- }
-
- @Override
- public int sub(int i, int j) {
- int result = i - j;
- System.out.println("方法内部,result:"+result);
- return result;
- }
-
- @Override
- public int mul(int i, int j) {
- int result = i * j;
- System.out.println("方法内部,result:"+result);
- return result;
- }
-
- @Override
- public int div(int i, int j) {
- int result = i / j;
- System.out.println("方法内部,result:"+result);
- return result;
- }
- }
测试:
- public class ProxyTest {
-
- @Test
- public void testProxy(){
- CalculatorStaticProxy proxy = new CalculatorStaticProxy(new CalculatorImpl());
- proxy.add(1, 2);
- }
-
- }
我们不需要手动去创建代理类 而是通过jdk中,给我们提供的一些方法 一些API 然后动态的为某一个目标类来创建他所对应的动态代理类 也就是说代理类 我们是提前没有的 我们需要JDK为我们提供的API在代码运行的过程中 动态的去帮我们去创建每天目标类所对应的动态代理类
所以我们的动态指的是 我们会动态的去生成目标类所对应的代理类
- public class ProxyFactory {
-
- private Object target;
-
- public ProxyFactory(Object target) {
- this.target = target;
- }
-
- public Object getProxy(){
- /**
- * ClassLoader loader:指定加载动态生成的代理类的类加载器
- * Class[] interfaces:获取目标对象实现的所有接口的class对象的数组
- * InvocationHandler h:设置代理类中的抽象方法如何重写
- */
- ClassLoader classLoader = this.getClass().getClassLoader();
- Class>[] interfaces = target.getClass().getInterfaces();
- InvocationHandler h = new InvocationHandler() {
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- Object result = null;
- try {
- System.out.println("日志,方法:"+method.getName()+",参数:"+ Arrays.toString(args));
- //proxy表示代理对象,method表示要执行的方法,args表示要执行的方法到的参数列表
- result = method.invoke(target, args);
- System.out.println("日志,方法:"+method.getName()+",结果:"+ result);
- } catch (Exception e) {
- e.printStackTrace();
- System.out.println("日志,方法:"+method.getName()+",异常:"+ e);
- } finally {
- System.out.println("日志,方法:"+method.getName()+",方法执行完毕");
- }
- return result;
- }
- };
- return Proxy.newProxyInstance(classLoader, interfaces, h);
- }
- }
测试类
- public class ProxyTest {
-
- @Test
- public void testProxy(){
- /* CalculatorStaticProxy proxy = new CalculatorStaticProxy(new CalculatorImpl());
- proxy.add(1, 2);*/
-
- ProxyFactory proxyFactory = new ProxyFactory(new CalculatorImpl());
- Calculator proxy = (Calculator) proxyFactory.getProxy();
- proxy.add(1,2);
- //proxy.div(1,0);
-
- }
-
- }
- public class ProxyTest {
-
- @Test
- public void testProxy(){
- /* CalculatorStaticProxy proxy = new CalculatorStaticProxy(new CalculatorImpl());
- proxy.add(1, 2);*/
-
- ProxyFactory proxyFactory = new ProxyFactory(new CalculatorImpl());
- Calculator proxy = (Calculator) proxyFactory.getProxy();
- // proxy.add(1,2);
- proxy.div(1,0);
-
- }
-
- }
总结:
/** * 动态代理有两种: * 1、jdk动态代理,要求必须有接口,最终生成的代理类和目标类实现相同的接口 * 在com.sun.proxy包下,类名为$proxy2 * 2、cglib动态代理,最终生成的代理类会继承目标类,并且和目标类在相同的包下 */