java吧 关注:1,184,964贴子:12,586,989

既然是最后一天摸鱼,那就来个技术帖吧

只看楼主收藏回复

二楼开整


IP属地:湖南1楼2021-02-09 10:13回复
    起源是之前有人问了我一个aop失效的问题:



    IP属地:湖南2楼2021-02-09 10:14
    回复
      当注解标记到类上面,Aspect使用@annotation去拦截时,会失效


      IP属地:湖南3楼2021-02-09 10:15
      回复
        标记到方法上即可被拦截


        IP属地:湖南4楼2021-02-09 10:16
        回复
          我的第一反应:wtf?
          不可能吧,事务没用过吗?写到类上不说常见,但是一定见过吧


          IP属地:湖南5楼2021-02-09 10:17
          回复
            既然这样,咱们就扣一下,容器启动中是怎么去生成拦截链的


            IP属地:湖南6楼2021-02-09 10:18
            回复
              我们都知道 spring给我们预留了两个炒鸡强大的扩展点:
              BeanPostProcessor和BeanFactoryPostProcessor,咱们就来说说我们我们的重头戏InfrastructureAdvisorAutoProxyCreator


              IP属地:湖南7楼2021-02-09 10:20
              回复


                IP属地:湖南8楼2021-02-09 10:21
                回复
                  InfrastructureAdvisorAutoProxyCreator实现了BeanPostProcessor.postProcessAfterInitialization,我们看看他到底做了什么


                  IP属地:湖南9楼2021-02-09 10:24
                  回复


                    IP属地:湖南10楼2021-02-09 10:24
                    回复
                      然后一路小跑进入到wrapIfNecessary方法,里面最最核心的就是getAdvicesAndAdvisorsForBean方法了;这里将直接获取到拦截链,也就是根据Aspect注解标记的类,根据匹配规则,获取最终匹配的类


                      IP属地:湖南11楼2021-02-09 10:27
                      回复
                        也是一路小跑,发现这个类最终走到了org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors方法,
                        List<Advisor> candidateAdvisors = findCandidateAdvisors();
                        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
                        第一条简单来说就是查询我们所有的aop拦截链,第二条就是规则匹配,这里的eligibleAdvisors,也就是我们最终需要的结果了


                        IP属地:湖南12楼2021-02-09 10:29
                        回复
                          最终规则匹配,走到了AopUtil.canApply,我们基本上的写法都是@Pointcut,所以 走到了if这里


                          IP属地:湖南13楼2021-02-09 10:34
                          回复
                            然后是一路小跑


                            IP属地:湖南14楼2021-02-09 10:35
                            回复
                              @Pointcut("@annotation(com.boot.aspect.Log)")这种拦截时,if里面走到了introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) 方法


                              IP属地:湖南15楼2021-02-09 10:37
                              回复