美文网首页
Java动态代理瞎想

Java动态代理瞎想

作者: 太大_453b | 来源:发表于2018-04-25 16:30 被阅读2次

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

    静态代理:

    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 -->
            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>3.2.4</version>
            </dependency>
    

    建议使用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动态代理瞎想

          本文链接:https://www.haomeiwen.com/subject/zqeylftx.html