动态代理

2021-12-13  本文已影响0人  java自力更生

什么是动态代理?

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

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
上一篇 下一篇

猜你喜欢

热点阅读