美文网首页
动态代理

动态代理

作者: java自力更生 | 来源:发表于2021-12-13 11:49 被阅读0次

    什么是动态代理?

    在聊动态代理之前,首先得先了解什么是代理以及静态代理。
    代理就是在一段方法的执行前后,加上前置操作与后置操作,常见做法有例如日志,事务等。
    以下这段代码就是静态代码的实现示例:

    public class StaticProxy {
    
        interface Operator{
    
            void op1();
    
            void op2();
    
        }
    
        public static class A implements Operator{
    
            public void op1() {
                System.out.println("A execute op1");
            }
    
            public void op2() {
                System.out.println("A execute op2");
            }
        }
    
        public static class LogHandler implements Operator{
    
            private Operator operator;
    
            public LogHandler(Operator operator){
                this.operator = operator;
            }
    
            public void op1() {
                System.out.println("log before execute op1");
                operator.op1();
                System.out.println("log after execute op1");
            }
    
            public void op2() {
                System.out.println("log before execute op2");
                operator.op2();
                System.out.println("log after execute op2");
            }
        }
    
    
        public static void main(String[] args) {
            Operator a = new A();
            Operator logA = new LogHandler(a);
            logA.op1();
            logA.op2();
        }
    
    }
    结果打印:
    log before execute op1
    A execute op1
    log after execute op1
    log before execute op2
    A execute op2
    log after execute op2
    

    静态代理有什么问题?

    1.不方便扩展修改,代码不易维护,以上例子同样是日志打印,在代理类中需要生成两个相同的方法,假设打印日志逻辑变更,需要修改所有的代理方法块

    动态代理实现之JDK代理

    JDK代理需要依赖于接口

    代码实现如下所示

    public class JdkProxy {
    
        interface Operator {
    
            void op1();
    
            void op2();
    
        }
    
        interface Operator2 {
    
            void op3();
    
        }
    
        public static class A implements Operator {
    
            public void op1() {
                System.out.println("A execute op1");
            }
    
            public void op2() {
                System.out.println("A execute op2");
            }
        }
    
        public static class B implements Operator2 {
    
            public void op3() {
                System.out.println("B execute op3");
            }
    
        }
    
        public static class LogHandler implements InvocationHandler {
    
            public Object object;
    
            public LogHandler(Object object) {
                this.object = object;
            }
    
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("before execute");
                Object invoke = method.invoke(object, args);
                System.out.println("after execute");
                return invoke;
            }
        }
    
    
        public static void main(String[] args) {
            A a = new A();
            Operator logA = (Operator) Proxy.newProxyInstance(Operator.class.getClassLoader(), new Class[]{Operator.class}, new LogHandler(a));
            logA.op1();
            logA.op2();
    
            B b = new B();
            Operator2 logB = (Operator2) Proxy.newProxyInstance(Operator2.class.getClassLoader(), new Class[]{Operator2.class}, new LogHandler(b));
            logB.op3();
        }
    
    }
    结果打印:
    before execute
    A execute op1
    after execute
    before execute
    A execute op2
    after execute
    before execute
    B execute op3
    after execute
    

    动态代理的优点

    以上案例说明,动态代理有用诸多优点
    1.节省重复代码,相较于静态代理,日志打印代码逻辑只需要保持一份,并且更新之后所有代理对象都能影响
    2.代理逻辑可以被多个接口复用

    动态代理实现之Cglib代理

    Cglib代理的原理是通过继承父类方法。

    代码实现如下所示

    public class CglibProxy {
    
        public static class A {
    
            public void op1() {
                System.out.println("A execute op1");
            }
    
            public void op2() {
                System.out.println("A execute op2");
            }
        }
    
        public static class B {
    
            public void op3() {
                System.out.println("B execute op3");
            }
    
        }
    
        public static class LogHandler implements MethodInterceptor {
    
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("before execute");
                Object invoke = methodProxy.invokeSuper(o, objects);
                System.out.println("after execute");
                return invoke;
            }
    
        }
    
        public static void main(String[] args) {
            Enhancer enhancerA = new Enhancer();
            enhancerA.setSuperclass(A.class);
            enhancerA.setCallback(new LogHandler());
            A a = (A) enhancerA.create();
            a.op1();
            a.op2();
            Enhancer enhancerB = new Enhancer();
            enhancerB.setSuperclass(B.class);
            enhancerB.setCallback(new LogHandler());
            B b = (B) enhancerB.create();
            b.op3();
        }
    
    }
    结果打印:
    before execute
    A execute op1
    after execute
    before execute
    A execute op2
    after execute
    before execute
    B execute op3
    after execute
    

    相关文章

      网友评论

          本文标题:动态代理

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