jdk动态代理和Cglib动态代理

ゝ一世哀愁。 2022-05-13 09:48 416阅读 0赞

jdk动态代理是基于反射,只能对实现了接口的类生成代理;cglib动态代理是基于继承的,针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法

jdk动态代理

首先编写一个接口MyInterface

  1. **
  2. * @version: 1.00.00
  3. * @description:
  4. * @author: panfan
  5. * @date: 2018/9/10 16:32
  6. * @history:
  7. */
  8. public interface MyInterface {
  9. void print();
  10. void print(String value);
  11. }

然后是接口的实现类

  1. /**
  2. * @version: 1.00.00
  3. * @description:
  4. * @author: panfan
  5. * @date: 2018/9/10 16:33
  6. * @history:
  7. */
  8. public class Target implements MyInterface {
  9. @Override
  10. public void print() {
  11. System.out.println("target print");
  12. }
  13. @Override
  14. public void print(String value) {
  15. System.out.println("target print === " + value);
  16. }
  17. }

编写代理类

  1. /**
  2. * @version: 1.00.00
  3. * @description: jdk动态代理类可以设置对一个接口中所有方法都执行同一类型操作,而不需像静态代理一样,每个方法都得设置
  4. * @author: panfan
  5. * @date: 2018/9/10 16:50
  6. * @history:
  7. */
  8. public class DynamicProxy implements InvocationHandler {
  9. // 被代理的实例
  10. private MyInterface myInterface;
  11. public DynamicProxy(MyInterface myInterface) {
  12. this.myInterface = myInterface;
  13. }
  14. public MyInterface create(){
  15. return (MyInterface) Proxy.newProxyInstance(
  16. myInterface.getClass().getClassLoader(),
  17. myInterface.getClass().getInterfaces(),
  18. this);
  19. }
  20. // 实现在接口中的每个方法前后都打印当前时间
  21. @Override
  22. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  23. System.out.println(System.currentTimeMillis() + "======before");
  24. method.invoke(myInterface, args);
  25. System.out.println(System.currentTimeMillis() + "======after");
  26. return null;
  27. }
  28. }

main函数测试一下

  1. public class DynamicProxyMain {
  2. public static void main(String[] args) {
  3. // 真实对象
  4. MyInterface realTarget = new Target();
  5. // 中介类
  6. DynamicProxy dynamicProxy = new DynamicProxy(realTarget);
  7. //动态产生一个代理类
  8. MyInterface proxy = dynamicProxy.create();
  9. //通过代理类,执行doSomething方法;
  10. proxy.print();
  11. proxy.print("panfan");
  12. }
  13. }

可以看到如下结果

70

CGLIB动态代理

还是使用刚才实现类Target,当做普通类来使用

  1. /**
  2. * @version: 1.00.00
  3. * @description: Cglib的动态代理是基于继承的,所以有final修饰的类不能代理
  4. * @author: panfan
  5. * @date: 2018/9/11 8:58
  6. * @history:
  7. */
  8. public class CglibProxy implements MethodInterceptor {
  9. private Object target;//业务类对象,供代理方法中进行真正的业务方法调用
  10. public Object bind(Object target){
  11. this.target = target; //给业务对象赋值
  12. Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类
  13. enhancer.setSuperclass(this.target.getClass()); //为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)
  14. //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦
  15. enhancer.setCallback(this);
  16. // 创建动态代理类对象并返回
  17. return enhancer.create();
  18. }
  19. @Override
  20. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  21. System.out.println("cglib before --------------------");
  22. Object ob = methodProxy.invokeSuper(o, objects);
  23. System.out.println("cglib after --------------------");
  24. return ob;
  25. }
  26. }

main函数测试一下

  1. public static void main(String[] args) {
  2. // 创建接口实现类
  3. Target target = new Target();
  4. // 创建代理类
  5. CglibProxy cglibProxy = new CglibProxy();
  6. // 获得代理生成的对象,传入的实现类是生成的代理类的父类
  7. Target target1 = (Target) cglibProxy.bind(target);
  8. target1.print();
  9. target1.print("panfan");
  10. }

可以看到如下效果

70 1

日后补充spring aop的介绍。。先水到这。

发表评论

表情:
评论列表 (有 0 条评论,416人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JDK动态代理CGLib动态代理

        JDK 动态代理是 JVM 根据传进来的对象,动态的创建对象的代理对象并返回。     CGLib 动态代理比较复杂,它是通过继承的方式来实现类的代理。 JDK