Spring中AOP的实现demo

刚入手Spring时感觉还好,凭借学到的反射和注解还能大致推断出底层的实现流程,但到AOP这一块的时候就感觉很迷了,为什么我调用的方法返回值发生了改变,为什么自己new的又不会了。。。
后来了解到CGLIB这种技术才慢慢解开了我的疑惑,这也是代码为什么可以一致直吸引我的地方,因为她可以满足洒家的欲望(求知欲)
在这里插入图片描述

行了不bb了,上代码
在这里插入图片描述
首先是CGLIB的依赖

<dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>3.3.0</version>
  </dependency>
public class Test2 {

   /*代理类需要实现MethodInterceptor接口并重写intercept方法*/
   static class Test2Proxy implements MethodInterceptor {
       @Override
       /*参数1:被代理类实例,参数2:被拦截的方法,参数3:被拦截方法的参数列表,参数4:代理方法*/
       public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
           /*调用被拦截的方法,此处不要用invoke方法,会被再次拦截一直递归直至栈堆溢出*/
           Object o1 = methodProxy.invokeSuper(o,objects);
           String s = "-------Before";
           /*可以任意更改原方法的返回值*/
           return o1+s;
       }
   }

   static class Test2Proxy2 implements MethodInterceptor{

       @Override
       public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
           return methodProxy.invokeSuper(o,objects);
       }
   }

   public String getHello(){
       return "Hello";
   }

   public String getHello2(){
       return "Hello2";
   }

   static void test(){
       Enhancer enhancer = new Enhancer();
       /*
       设置被代理类
       从各种命名中的super不难看出,动态代理类是被代理类的子类,
       而拦截的方法也是对父类方法的重写
       所以这也是为什么被final修饰的类和方法不能被代理的原因
       */
       enhancer.setSuperclass(Test2.class);
       /*设置单个代理类*/
       enhancer.setCallback(new Test2Proxy2());
       /*配置回调过滤器控制方法回调时使用的代理类*/
       CallbackFilter cbf = method -> {
           /*这种equals的使用(已知比未知)也算是一种良好的编程习惯,可以有效避免空指针*/
           if("getHello2".equals(method.getName())){
               return 1;
           }
           //这里返回的int是代表setCallbacks方法中传递的数组的索引,来决定使用哪一个代理类
           return 0;
       };
       /*设置多个代理类对象,会使setCallback方法的配置失效*/
       enhancer.setCallbacks(new Callback[]{new Test2Proxy(),new Test2Proxy2()});
       /*设置拦截方法的过滤器*/
       enhancer.setCallbackFilter(cbf);
       /*创建代理类对象*/
       Test2 t2 = (Test2) enhancer.create();
       System.out.println(t2.getClass()+"\n"+t2.getHello()+"\n"+t2.getHello2());
   }

   public static void main(String[] args) {
       test();
   }
}

控制台:
在这里插入图片描述

确实,CGLIB比JDK动态代理功能更加强大
牛哔!
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值