动态代理的两种方式

动态代理的两种方式:JDK方式和cglib方式。

一.JDK方式,在这个方式中,需要目标对象,目标对象的接口,增强方法,三个类。

public interface TargetInterface {
    public void save();
}

public class Target implements TargetInterface{
    @Override
    public void save() {
        System.out.println("saving");
    }
}

创建了简单的目标类,用于被增强。接下来创建增强方法类。

public class Advance {
    public void before(){
        System.out.println("前置增强");
    }

    public void after(){
        System.out.println("后置增强");
    }
}

创建测试类,增强target的功能。

public class ProxyTest {
    public static void main(String[] args) {
        Target target = new Target();
        Advance a = new Advance();
        TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                a.before();
                method.invoke(target,args);
                a.after();
                return null;
            }
        });
        proxy.save();
    }
}

在main方法中对target方法进行了增强,增强的主要代码在invoke()方法内部实现。

二,使用cglib

使用cglib需要引入对应的jar包或者maven坐标(针对于老版本的spring而言,新版本的spring5已经在core包下包含了cglib)。

public class Target{
    @Override
    public void save() {
        System.out.println("saving");
    }
}
public class Advance {
    public void before(){
        System.out.println("前置增强");
    }

    public void after(){
        System.out.println("后置增强");
    }
}

同样的有如上类的创建。不过在测试类中就不一样了

public class ProxyTest {
    public static void main(String[] args) {
        Target target = new Target();
        Advance a = new Advance();
        //1.创建增强器
        Enhancer enhancer = new Enhancer();
        //2.设置父类
        enhancer.setSuperclass(Target.class);
        //3.设置回调
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                a.before();
                Object invoke = method.invoke(target, objects);
                a.after();
                return invoke;
            }
        });
        //4.设置代理对象
        Target target1 = (Target) enhancer.create();
        target1.save();
    }
}

设置回调时的intercept方法就如同第一种方法中的invoke方法。


版权声明:本文为m0_57697979原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。