Java动态代理瞎想

代理模式分为动态代理和静态代理

静态代理:

  1. 定义一个人类的接口:Person
  2. 实现类:Student
  3. 代理类:StuProxy 实现Person 在重写方法中调用Student,从而实现消息过滤,日志插入等AOP功能

动态代理:

  • JDK动态代理
        Student student = new Student();
        Person person = (Person)Proxy.newProxyInstance(student.getClass().getClassLoader(), student.getClass().getInterfaces(), (proxy, method, params) -> {
            System.out.println("做一个消息的过滤before");
            method.invoke(student, params);
            System.out.println("做一个消息的过滤after");
            return null;
        });
        person.sayHello();
  1. 解释: java.lang.reflect.Proxy创建一个代理对象
    参数分三个,第一个是classloader, 第二个接口数组,第三个是InvocationHandlerc增强invoke方法before, after可以写自己的需要的方法
  2. 特点:需要传入接口,newProxyInstance通过接口的反射拿到方法名等属性,在newProxyInstance定义中必须用接口模式,比较符合面向对象的思想
  3. 最终生成的代理类extend Proxy并实现了定义的传入的接口
  • CGLIB动态代理

首先定义一个MyMethod自己的方法实现MethodInterceptor,增强intercept方法同理

    static class MyMethod implements MethodInterceptor{
        private Student stu;
        public MyMethod(Student student){
            stu = student;
        }

        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println(method);
            System.out.println(objects.length);
            System.out.println(methodProxy.getClass());
            return methodProxy.invoke(stu, objects);
        }
    }

参数介绍:

  1. o 为对象
  2. method 调用的方法名
  3. objects为参数
  4. methodProxy:生成的代理对象的方法实例
method: public void com.firesoon.drgs.exe.test.Student.say()
objects为参数: [Ljava.lang.Object;@31b7dea0
methodProxy: class net.sf.cglib.proxy.MethodProxy

pom.xml文件

        
        
            cglib
            cglib
            3.2.4
        

建议使用3.2.4 在3.2.6版本中new Enhancer()过程中出现包冲突的问题

然后在调用

    public static void main(String[] args) {
        Student student = new Student();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(student.getClass());
        enhancer.setCallback(new MyMethod(student));
        Student p = (Student)enhancer.create();
        p.say();
    }
  1. 根据实现类实现的代理的不需要传入接口
  2. 代理类对象是由Enhancer类创建的。Enhancer是CGLIB的字节码增强器
  3. superClass:实现类的class类生成二进制字节码文件,通过class对象反射出代理对象实例
  4. 在最后执行的时候执行的时候methodProxy.invoke();

你可能感兴趣的:(Java动态代理瞎想)