首页 » 编程知识 » Design » jdk动态代理和cglib动态代理

jdk动态代理和cglib动态代理

 

jdk动态代理

原理:JDK动态代理的代理对象在创建时,需要使用业务实现类所实现的接口作为参数(因为在后面代理方法时需要根据接口内的方法名进行调用)。如果业务实现类是没有实现接口而是直接定义业务方法的话,就无法使用JDK动态代理了。并且,如果业务实现类中新增了接口中没有的方法,这些方法是无法被代理的(因为无法被调用)。

1. 接口
public interface Person {
    public void teache();
}
2. 实现类
    public class Teacher implements Person {
    @Override
    public void teache() {
        System.out.println("老师以他的独特方式教书");
    }
}
3.实现invocationHandler的代理类
    public class ProxyModel implements InvocationHandler {
    private Person person;
    public ProxyModel(Person person) {
        this.person = person;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        method.invoke(person,args);
        after();
        return null;
    }

    public void before() {
        System.out.println("教书之前备课");
    }

    public void after() {
        System.out.println("教书之后总结课程");
    }
}
4.客户端实现
public class ProxyTest {

public static void main(String[] args) {
    Person teacher = new Teacher();
    ProxyModel proxyModel = new ProxyModel(teacher);
    Person o = (Person) Proxy.newProxyInstance(proxyModel.getClass().getClassLoader(),teacher.getClass().getInterfaces(), proxyModel);
    o.teache();
}

}

cglib动态代理

原理:cglib是针对类来实现代理的,原理是对指定的业务类生成一个子类,并覆盖其中业务方法实现代理。因为采用的是继承,所以不能对final修饰的类进行代理

1. 业务实现类
    public class Dog {
    public void run() {
        System.out.println("狗沿着大路一直跑");
    }
}
2. cglib代理类
    public class CglibProxy implements MethodInterceptor {

    private Object target;

    public Object getInstance(Object obj) {
        this.target = obj;
        Enhancer enhancer = new Enhancer(); // 创建加强器
        enhancer.setSuperclass(this.target.getClass()); // 设置父类
        // 设置回调,代理类上的每一个方法都会回调,并且每个方式需要实现interceptor方法
        enhancer.setCallback(this);
        // 创建代理对象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("执行方法之前");
        methodProxy.invokeSuper(o,args);
        System.out.println("执行方法之后");
        return null;
    }
}
3.客户端实现
    public class CglibTest {

    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        Dog dog = (Dog) cglibProxy.getInstance(new Dog());

        dog.run();
    }
}

原文链接:jdk动态代理和cglib动态代理,转载请注明来源!

0