Spring源码学习笔记(7)

Spring源码学习笔记(七)

  前言--

    最近花了些时间看了《Spring源码深度解析》这本书,算是入门了Spring的源码吧。打算写下系列文章,回忆一下书的内容,总结代码的运行流程。推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的《Spring源码深度解析》这本书,会是个很好的入门



      写前说句话, 开篇不尴尬 ---- 接下的这一篇当中, 我们将来回顾 Spring 中 AOP 功能的实现流程。  早上精力充沛, 开始新一天的学习 \(^o^)/~



      接触过 Spring 框架的同学都知道, Spring 中使用的两个功能无非就是依赖注入的 DI 以及面向切面编程的 AOP, 其中 AOP 又包括了动态 AOP 和静态 AOP 两个方向。 首先,我们来看看 Spring 是如何实现我们最常接触到的动态 AOP 的。

动态AOP

    启用 Spring 的 AOP 功能, 需要我们在 Spring 的配置文件中添加 <aop:aspectj-autoproxy/> 。我们将从这个配置为入口看看 AOP 的实现过程。

     在 AopNamespaceHandler 中, 有一下初始化代码:

 1 public class AopNamespaceHandler extends NamespaceHandlerSupport {
 2     public AopNamespaceHandler() {
 3     }
 4
 5     public void init() {
 6         this.registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
 7         //第一步:  在此注册 AOP 功能
 8         this.registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
 9         this.registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
10         this.registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
11     }
12 }

    进入 AspectJAutoProxyBeanDefinitionParser 类中, 发现该类实现了 BeanDefinitionParser 接口, 所以查看该类的 parse() 方法, 其实现逻辑:

1     public BeanDefinition parse(Element element, ParserContext parserContext) {
2           //第一步:  注册 AnnotationAwareAspectJAutoProxyCreator
3
4      AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
5         this.extendBeanDefinition(element, parserContext);
6         return null;
7     }

    进入 registerAspectJAnnotationAutoProxyCreatorIfNecessary() 方法中查看实现逻辑:

1     public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
2         //第一步:  注册 AutoProxyCreator 的 BeanDefinition
3         BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement));
4         //第二步:   处理 proxy-target-class 和 expose-proxy 属性
5     useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
6         //第三步:  通知监听器, beanDefinition 的 className 为 AnnotationAwareAspectJAutoProxyCreator
7     registerComponentIfNecessary(beanDefinition, parserContext);
8     }

    进入 registerAspectJAnnotationAutoProxyCreatorIfNecessary() 方法, 一步步查看三个方法中的每个方法.

    首先 registerAspectJAnnotationAutoProxyCreatorIfNecessary(), 注册实现 AOP 功能的 AnnotationAwareAspectJAutoProxyCreator 类:

1     public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
2         // 第一步:  继续方法的调用
3         return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
4     }
 1     private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
 2         Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
 3         //第一步: 判断是否已经存在 AutoProxyCreator 且存在的 Creator 和当前的不一致, 需要决定使用哪个
 4         if(registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
 5             BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
 6             if(!cls.getName().equals(apcDefinition.getBeanClassName())) {
 7                 int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
 8                 int requiredPriority = findPriorityForClass(cls);
 9                 if(currentPriority < requiredPriority) {
10                     apcDefinition.setBeanClassName(cls.getName());
11                 }
12             }
13             //第二步:  存在 AutoProxyCreator 且与当前的一致, 则直接返回
14             return null;
15         } else {
16             //第三步:  重新创建 AutoProxyCreator
17             RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
18             beanDefinition.setSource(source);
19             beanDefinition.getPropertyValues().add("order", Integer.valueOf(-2147483648));
20             beanDefinition.setRole(2);
21             registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
22             return beanDefinition;
23         }
24     }

    简单易懂, 条理清晰, 我喜欢 ~( ̄▽ ̄)~*

    接下来在 registerAspectJAnnotationAutoProxyCreatorIfNecessary() 方法中, 第二步对 proxy-target-class 和 expose-proxy 属性的处理的 useClassProxyingIfNecessary() 逻辑:

 1     private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
 2         if(sourceElement != null) {
 3             //第一步: 处理 proxy-target-class
 4             boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute("proxy-target-class")).booleanValue();
 5             if(proxyTargetClass) {
 6                 AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
 7             }
 8             //第二步:  处理 expose-proxy
 9             boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute("expose-proxy")).booleanValue();
10             if(exposeProxy) {
11                 AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
12             }
13         }
14
15     }

    进入处理 proxy-target-class 属性的逻辑:

1     public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
2          if(registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
3             BeanDefinition definition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
4             //第一步:  为 BeanDefinition 添加 proxyTargetClass 属性
5             definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
6         }
7
8     }

    进入处理 expose-proxy 属性的逻辑:

1     static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
2         if(registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
3             BeanDefinition definition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
4             //第一步:  为 BeanDefinition 添加 exposeProxy 属性
5             definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
6         }
7
8     }

    实现的逻辑很简单, 为 BeanDefinition 添加了不同的属性。 Spring 使用 JDK 的动态代理 或者使用 CGLIB 创建代理类, 使用 proxy-target-class 配置来决定使用哪种方式,需要注意其中使用的区别:

    1, 强制使用 CGLIB 生成代理类, 配置  <aop:config proxy-target-class="true"/>;

   2, 使用 CGLIB 和 @AspectJ 自动代理时, 配置  <aop:aspectj-autoproxy proxy-target-class="true"/>;

   3, 只有在类有实现接口的情况下, 才能使用 JDK 的动态代理生成代理类, 使用 CGLIB 的时候需要注意不能通知 final 方法;

    而对于 expose-proxy 的是情况是, 在代理的目标类里, 类方法调用自身的方法时, 被调用方法不会再调用方法的增强逻辑, 若需要调用, 则需要配置:

      <aop:aspectj-autoproxy expose-proxy="true"/>

    讲了这么多, 发现我们只是看到了 Spring AOP 的入口方法以及基础的实现类, 而真正的创建 代理类 的逻辑我们并没有看到,因此,这就是我们接下来要做的事情。

    

    上面讲到 Spring AOP 的基本的实现类是 AnnotationAwareAspectJAutoProxyCreator , 使用 IntelliJ 的功能, 我们瞄一下该类的层次结构:

    

    可以看到 AnnotationAwareAspectJAutoProxyCreator  实现了 BeanPostProcessor 类,查看其实现的方法, 在父类 AbstractAutoProxyCreator 中:

 1     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
 2         if(bean != null) {
 3             //第一步: 构建对应 bean 的 className_beanName 的 key
 4             Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
 5             if(!this.earlyProxyReferences.contains(cacheKey)) {
 6                 //第二步: 需要代理, 封装 bean
 7                 return this.wrapIfNecessary(bean, beanName, cacheKey);
 8             }
 9         }
10
11         return bean;
12     }
 1     protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
 2         //第一步: 已经处理过直接返回
 3         if(beanName != null && this.targetSourcedBeans.contains(beanName)) {
 4             return bean;
 5         } else
 6          //第二步:  无需增强直接返回
 7  if(Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
 8             return bean;
 9         } //第三步: 略过 基础类 或者 配置了 不用代理
10             else if(!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
11             //第四步: 获取 增强器
12             Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
13             //第五步: 存在增强则增强
14             if(specificInterceptors != DO_NOT_PROXY) {
15                 this.advisedBeans.put(cacheKey, Boolean.TRUE);
16                  //第六步:  用增强器创建代理类
17                 Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
18                 this.proxyTypes.put(cacheKey, proxy.getClass());
19                 return proxy;
20             } else {
21                 this.advisedBeans.put(cacheKey, Boolean.FALSE);
22                 return bean;
23             }
24         } else {
25             this.advisedBeans.put(cacheKey, Boolean.FALSE);
26             return bean;
27         }
28     }

    看起来很简单, 是否爽了一把, 接下来分分点分析其中的逻辑。

一, 获取增强器

1     protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
2         List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
3         return advisors.isEmpty()?DO_NOT_PROXY:advisors.toArray();
4     }
 1     protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
 2         //第一步: 查询所有的增强
 3         List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
 4         //第二步: 查询适合的增强
 5         List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
 6         this.extendAdvisors(eligibleAdvisors);
 7         if(!eligibleAdvisors.isEmpty()) {
 8             eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
 9         }
10
11         return eligibleAdvisors;
12     }

    我不想解释, 你也不想听!!!( *^-^)ρ(*╯^╰)

    查询所有的增强的方法 findCandidateAdvisors() 的实现逻辑, 在 AnnotationAwareAspectJAutoProxyCreator 类中:

1     protected List<Advisor> findCandidateAdvisors() {
2         //第一步: 调用父类加载 XML 文件的方法
3         List<Advisor> advisors = super.findCandidateAdvisors();
4         //第二步:   类扩展父类实现的通过注解获取增强的方法
5          advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
6         return advisors;
7     }

    由前面的 Diagram 图可以看出, AnnotationAwareAspectJAutoProxyCreator 类继承 AbstractAdvisorAutoProxyCreator 类, 子类在父类获取 XML 文件的增强之外, 还实现了从 @AspectJ 获取增强的方法。

    在 findCandidateAdvisors() 方法中, 第二步通过注解获取增强的方法 buildAspectJAvisors() 的实现逻辑:

 1     public List<Advisor> buildAspectJAdvisors() {
 2         List<String> aspectNames = null;
 3         synchronized(this) {
 4             aspectNames = this.aspectBeanNames;
 5             if(aspectNames == null) {
 6                 List<Advisor> advisors = new LinkedList();
 7                 List<String> aspectNames = new LinkedList();
 8                 //第一步: 获取所有的 beanName
 9                 String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
10                 String[] var18 = beanNames;
11                 int var19 = beanNames.length;
12                 //第二步: 遍历所有的 beanName 找出增强方法
13                 for(int var7 = 0; var7 < var19; ++var7) {
14                     String beanName = var18[var7];
15                     if(this.isEligibleBean(beanName)) {
16                         //第三步: 获取 bean 的类型
17                         Class<?> beanType = this.beanFactory.getType(beanName);
18                         //第四步:  存在 AspectJ 注解 (此处的 advisorFactory 是 AbstractAspectJAdvisorFactory)
19                         if(beanType != null && this.advisorFactory.isAspect(beanType)) {
20                             aspectNames.add(beanName);
21                             AspectMetadata amd = new AspectMetadata(beanType, beanName);
22                             if(amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
23                                 MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
24                                 //第五步:解析 AspectJ 注解的增强方法
25                                 List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
26                                 //第六步:  加入缓存的操作
27                                 if(this.beanFactory.isSingleton(beanName)) {
28                                     this.advisorsCache.put(beanName, classAdvisors);
29                                 } else {
30                                     this.aspectFactoryCache.put(beanName, factory);
31                                 }
32
33                                 advisors.addAll(classAdvisors);
34                             } else {
35                                 if(this.beanFactory.isSingleton(beanName)) {
36                                     throw new IllegalArgumentException("Bean with name ‘" + beanName + "‘ is a singleton, but aspect instantiation model is not singleton");
37                                 }
38
39                                 MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
40                                 this.aspectFactoryCache.put(beanName, factory);
41                                 advisors.addAll(this.advisorFactory.getAdvisors(factory));
42                             }
43                         }
44                     }
45                 }
46
47                 this.aspectBeanNames = aspectNames;
48                 return advisors;
49             }
50         }
51
52         if(aspectNames.isEmpty()) {
53             return Collections.emptyList();
54         } else {
55             List<Advisor> advisors = new LinkedList();
56             Iterator var3 = aspectNames.iterator();
57             //第七步:  加入缓存的操作
58             while(var3.hasNext()) {
59                 String aspectName = (String)var3.next();
60                 List<Advisor> cachedAdvisors = (List)this.advisorsCache.get(aspectName);
61                 if(cachedAdvisors != null) {
62                     advisors.addAll(cachedAdvisors);
63                 } else {
64                     MetadataAwareAspectInstanceFactory factory = (MetadataAwareAspectInstanceFactory)this.aspectFactoryCache.get(aspectName);
65                     advisors.addAll(this.advisorFactory.getAdvisors(factory));
66                 }
67             }
68
69             return advisors;
70         }
71     }

    在  buildAspectJAdvisors() 方法中, 第五步获取增强器的 getAdvisors() 的实现, 实现在 ReflectiveAspectJAdvisorFactory 类中:

 1    public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory maaif) {
 2         //第一步: 获取标记为 AspectJ 的类
 3         Class<?> aspectClass = maaif.getAspectMetadata().getAspectClass();
 4         //第二步: 获取标记为 AspectJ 的名字
 5         String aspectName = maaif.getAspectMetadata().getAspectName();
 6         this.validate(aspectClass);
 7         MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(maaif);
 8         List<Advisor> advisors = new LinkedList();
 9         //第三步: 获取所有的方法
10         Iterator var6 = this.getAdvisorMethods(aspectClass).iterator();
11         //第四步:  遍历所有的方法
12         while(var6.hasNext()) {
13             Method method = (Method)var6.next();
14             Advisor advisor = this.getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
15             if(advisor != null) {
16                 advisors.add(advisor);
17             }
18         }
19         //第五步: 增强器不为空且配置增强延迟初始化则封装同步化实例增强器
20         if(!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
21             Advisor instantiationAdvisor = new ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
22             advisors.add(0, instantiationAdvisor);
23         }
24         //第六步:  获取 DeclareParents 注解
25         Field[] var12 = aspectClass.getDeclaredFields();
26         int var13 = var12.length;
27
28         for(int var14 = 0; var14 < var13; ++var14) {
29             Field field = var12[var14];
30             Advisor advisor = this.getDeclareParentsAdvisor(field);
31             if(advisor != null) {
32                 advisors.add(advisor);
33             }
34         }
35
36         return advisors;
37     }

    在 getAdvisors() 方法中, 第四步普通增强器的获取方法 getAdvisor()  方法的实现逻辑:

1     public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {
2         this.validate(aif.getAspectMetadata().getAspectClass());
3         //第一步:  切点信息的获取 封装类
4         AspectJExpressionPointcut ajexp = this.getPointcut(candidateAdviceMethod, aif.getAspectMetadata().getAspectClass());
5         //第二步: 根据切点信息生成增强器  也是封装类
6         return ajexp == null?null:new InstantiationModelAwarePointcutAdvisorImpl(this, ajexp, aif, candidateAdviceMethod, declarationOrderInAspect, aspectName);
7     }

    在 getAdvisor() 方法中, 第一步切点信息的获取方法 getPointcut() 方法的实现逻辑, 封装成 AspectJExpressionPointcut 类:

 1     private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
 2         //第一步: 获取方法上的注解
 3         AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
 4         if(aspectJAnnotation == null) {
 5             return null;
 6         } else {
 7             //第二步:  封装获取的信息
 8             AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class[0]);
 9             ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
10             return ajexp;
11         }
12     }

    第一步中获取方法上的注解 findAspectJAnnotationOnMethod() 方法的实现逻辑:   (这个方法值得注意一下~~~~~~~~~~~~~)

 1     protected static AbstractAspectJAdvisorFactory.AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
 2         //第一步: 列举所有的 注解的类
 3         Class<?>[] classesToLookFor = new Class[]{Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
 4         Class[] var2 = classesToLookFor;
 5         int var3 = classesToLookFor.length;
 6         //第二步:遍历所有的注解类 匹配注解信息
 7         for(int var4 = 0; var4 < var3; ++var4) {
 8             Class<?> c = var2[var4];
 9             AbstractAspectJAdvisorFactory.AspectJAnnotation<?> foundAnnotation = findAnnotation(method, c);
10             if(foundAnnotation != null) {
11                 return foundAnnotation;
12             }
13         }
14
15         return null;
16     }

    在  findAspectJAnnotationOnMethod() 方法中, 第二步获取指定方法上的注解并使用 AspectJAnnotation 封装信息的 findAnnotation() 实现逻辑:

1     private static <A extends Annotation> AbstractAspectJAdvisorFactory.AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
2         //第一步: 匹配注解类
3         A result = AnnotationUtils.findAnnotation(method, toLookFor);
4         //第二步: 封装到类中
5         return result != null?new AbstractAspectJAdvisorFactory.AspectJAnnotation(result):null;
6     }

    瞄一下匹配注解类的方法 AnnotationUtils.findAnnotation()  的实现逻辑:

 1     public static <A extends Annotation> A findAnnotation(Method method, Class<A> annotationType) {
 2         //第一步:  获取注解
 3         A annotation = getAnnotation(method, annotationType);
 4         //第二步:  获取 class
 5         Class<?> clazz = method.getDeclaringClass();
 6         if(annotation == null) {
 7             annotation = searchOnInterfaces(method, annotationType, clazz.getInterfaces());
 8         }
 9         //第三步:  递归到父类去查找
10         while(annotation == null) {
11             clazz = clazz.getSuperclass();
12             if(clazz == null || clazz.equals(Object.class)) {
13                 break;
14             }
15
16             try {
17                 //第四步: 获取类中指定的方法 及 方法上的注解
18                 Method equivalentMethod = clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
19                 annotation = getAnnotation(equivalentMethod, annotationType);
20             } catch (NoSuchMethodException var5) {
21                 ;
22             }
23
24             if(annotation == null) {
25                 annotation = searchOnInterfaces(method, annotationType, clazz.getInterfaces());
26             }
27         }
28
29         return annotation;
30     }

    在 findAnnotation() 方法中, 深入的实现逻辑并看不懂, 应该是从 getAnnotation()searchOnInterfaces() 方法入口, 方法的重载也很多, 容易晕!!!

    避实就虚, 抱大腿, 回到 getAdvisor() 方法中, 封装增强器的 InstantiationModelAwarePointcutAdvisorImpl 类是 Advisor 的实现类, 瞄一下该类的构造器:

 1   public InstantiationModelAwarePointcutAdvisorImpl(AspectJAdvisorFactory af, AspectJExpressionPointcut ajexp, MetadataAwareAspectInstanceFactory aif, Method method, int declarationOrderInAspect, String aspectName) {
 2         // 例子 :@Before("test()")
 3         //第一步: 被切入方法 test()
 4         this.declaredPointcut = ajexp;
 5         //第二步: 切入的方法
 6         this.method = method;
 7         this.atAspectJAdvisorFactory = af;
 8         this.aspectInstanceFactory = aif;
 9         this.declarationOrder = declarationOrderInAspect;
10         //第三步: 切面的名称
11         this.aspectName = aspectName;
12         //第四步:pointcut 是懒加载类型
13         if(aif.getAspectMetadata().isLazilyInstantiated()) {
14             Pointcut preInstantiationPointcut = Pointcuts.union(aif.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
15             this.pointcut = new InstantiationModelAwarePointcutAdvisorImpl.PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aif, (InstantiationModelAwarePointcutAdvisorImpl.SyntheticClass_1)null);
16             this.lazy = true;
17         } else {
18             //第五步:  单例 aspect
19             this.instantiatedAdvice = this.instantiateAdvice(this.declaredPointcut);
20             this.pointcut = this.declaredPointcut;
21             this.lazy = false;
22         }
23
24     }

    在该构造方法中, 根据注解信息初始化对应的增强器 instantiateAdvice() 方法的实现逻辑:

1     private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
2         //第一步: 继续调用方法
3         return this.atAspectJAdvisorFactory.getAdvice(this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
4     }

    这里的  AspectJAdvisorFactory 类型的 atAspectJAdvisorFactory 对象是 ReflectiveAspectJAdvisorFactory 的实例,该类中的 getAdvice() 方法的实现逻辑:

 1     public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut ajexp, MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {
 2         Class<?> candidateAspectClass = aif.getAspectMetadata().getAspectClass();
 3         this.validate(candidateAspectClass);
 4         AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
 5         if(aspectJAnnotation == null) {
 6             return null;
 7         } else if(!this.isAspect(candidateAspectClass)) {
 8             throw new AopConfigException("Advice must be declared inside an aspect type: Offending method ‘" + candidateAdviceMethod + "‘ in class [" + candidateAspectClass.getName() + "]");
 9         } else {
10             if(this.logger.isDebugEnabled()) {
11                 this.logger.debug("Found AspectJ method: " + candidateAdviceMethod);
12             }
13
14             Object springAdvice;
15             //第一步:  对不同增强器的方法封装不同的类
16             switch(ReflectiveAspectJAdvisorFactory.SyntheticClass_1.$SwitchMap$org$springframework$aop$aspectj$annotation$AbstractAspectJAdvisorFactory$AspectJAnnotationType[aspectJAnnotation.getAnnotationType().ordinal()]) {
17             case 1:
18                 springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, ajexp, aif);
19                 break;
20             case 2:
21                 springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, ajexp, aif);
22                 break;
23             case 3:
24                 springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, ajexp, aif);
25                 AfterReturning afterReturningAnnotation = (AfterReturning)aspectJAnnotation.getAnnotation();
26                 if(StringUtils.hasText(afterReturningAnnotation.returning())) {
27                     ((AbstractAspectJAdvice)springAdvice).setReturningName(afterReturningAnnotation.returning());
28                 }
29                 break;
30             case 4:
31                 springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, ajexp, aif);
32                 AfterThrowing afterThrowingAnnotation = (AfterThrowing)aspectJAnnotation.getAnnotation();
33                 if(StringUtils.hasText(afterThrowingAnnotation.throwing())) {
34                     ((AbstractAspectJAdvice)springAdvice).setThrowingName(afterThrowingAnnotation.throwing());
35                 }
36                 break;
37             case 5:
38                 springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, ajexp, aif);
39                 break;
40             case 6:
41                 if(this.logger.isDebugEnabled()) {
42                     this.logger.debug("Processing pointcut ‘" + candidateAdviceMethod.getName() + "‘");
43                 }
44
45                 return null;
46             default:
47                 throw new UnsupportedOperationException("Unsupported advice type on method " + candidateAdviceMethod);
48             }
49              //第二步:  配置增强器
50              ((AbstractAspectJAdvice)springAdvice).setAspectName(aspectName);
51             ((AbstractAspectJAdvice)springAdvice).setDeclarationOrder(declarationOrderInAspect);
52             String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
53             if(argNames != null) {
54                 ((AbstractAspectJAdvice)springAdvice).setArgumentNamesFromStringArray(argNames);
55             }
56
57             ((AbstractAspectJAdvice)springAdvice).calculateArgumentBindings();
58             return (Advice)springAdvice;
59         }
60     }

    从上面的 getAdvice() 方法中,我们可以看出, 对不同的注解 Spring 会生成不同的 Advice 进行处理。

     对 @AtBefore 注解, 对应的是 AspectJMethodBeforeAdvice :  (逻辑是对的, 但是找不到 AspectJMethodBeforeAdvice 和 MethodBeforeAdviceInterceptor 的关系  ( ̄~ ̄) !)

 1 public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
 2     private MethodBeforeAdvice advice;
 3
 4     public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
 5         //第一步: 构造函数中传入一个 MethodBeforeAdvice
 6         Assert.notNull(advice, "Advice must not be null");
 7         this.advice = advice;
 8     }
 9     //第二步: 调用 before() 方法
10     public Object invoke(MethodInvocation mi) throws Throwable {
11         this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
12         return mi.proceed();
13     }
14 }

    其中的 advice 属性是 AspectJMethodBeforeAdvice 类的, 查看 before() 方法:

1     public void before(Method method, Object[] args, Object target) throws Throwable {
2         this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null);
3     }
1     protected Object invokeAdviceMethod(JoinPointMatch jpMatch, Object returnValue, Throwable ex) throws Throwable {
2         return this.invokeAdviceMethodWithGivenArgs(this.argBinding(this.getJoinPoint(), jpMatch, returnValue, ex));
3     }
 1     protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
 2         //第一步: 获取参数
 3         Object[] actualArgs = args;
 4         if(this.aspectJAdviceMethod.getParameterTypes().length == 0) {
 5             actualArgs = null;
 6         }
 7
 8         try {
 9             ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
10             //第二步: 调用方法
11             return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
12         } catch (IllegalArgumentException var4) {
13             throw new AopInvocationException("Mismatch on arguments to advice method [" + this.aspectJAdviceMethod + "]; pointcut expression [" + this.pointcut.getPointcutExpression() + "]", var4);
14         } catch (InvocationTargetException var5) {
15             throw var5.getTargetException();
16         }
17     }

    而对于 @After 注解, 对应的是 AspectJAfterAdvice 类 :

 1 public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice {
 2     public AspectJAfterAdvice(Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
 3         super(aspectJBeforeAdviceMethod, pointcut, aif);
 4     }
 5
 6     public Object invoke(MethodInvocation mi) throws Throwable {
 7         Object var2;
 8         try {
 9             //第一步: 调用 被切入方法
10             var2 = mi.proceed();
11         } finally {
12             //第二步:  调用 切入方法
13             this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null);
14         }
15
16         return var2;
17     }
18
19     public boolean isBeforeAdvice() {
20         return false;
21     }
22
23     public boolean isAfterAdvice() {
24         return true;
25     }
26 }

    way so far, way so hard!  可能已经忘了, 回到 getAdvisors() 方法的第五步中, 同步实例化增强器  SyntheticInstantiationAdvisor 的作用, 该类是 ReflectiveAspectJAdvisorFactory 的一个内部类:

 1     protected static class SyntheticInstantiationAdvisor extends DefaultPointcutAdvisor {
 2         public SyntheticInstantiationAdvisor(final MetadataAwareAspectInstanceFactory aif) {
 3             super(aif.getAspectMetadata().getPerClausePointcut(), new MethodBeforeAdvice() {
 4                 //第一步: 目标方法前调用 before 方法
 5                 public void before(Method method, Object[] args, Object target) {
 6                     //第二步: 初始化 aspect
 7                     aif.getAspectInstance();
 8                 }
 9             });
10         }
11     }

    在 getAdvisors() 方法中, 第六步获取 DeclareParents 注解的作用主要是处理 IntroductionAdvisor ,具体干什么的其实我也没见过 (? _ ?)

 1     private Advisor getDeclareParentsAdvisor(Field introductionField) {
 2         DeclareParents declareParents = (DeclareParents)introductionField.getAnnotation(DeclareParents.class);
 3         if(declareParents == null) {
 4             return null;
 5         } else if(DeclareParents.class.equals(declareParents.defaultImpl())) {
 6             throw new IllegalStateException("defaultImpl must be set on DeclareParents");
 7         } else {
 8             //  封装信息
 9             return new DeclareParentsAdvisor(introductionField.getType(), declareParents.value(), declareParents.defaultImpl());
10         }
11     }

    不骗你, 这么多的代码,其实只是 findEligibleAdvisors() 方法中的 findCandidateAdvisors() 方法的深入, 找到所有的增强器之后还需要找合适的增强器 findAdvisorsThatCanApply():

 1     protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
 2         ProxyCreationContext.setCurrentProxiedBeanName(beanName);
 3
 4         List var4;
 5         try {
 6             //第一步:  过滤已经得到的 advisors
 7             var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
 8         } finally {
 9             ProxyCreationContext.setCurrentProxiedBeanName((String)null);
10         }
11
12         return var4;
13     }
 1     public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
 2         if(candidateAdvisors.isEmpty()) {
 3             return candidateAdvisors;
 4         } else {
 5             List<Advisor> eligibleAdvisors = new LinkedList();
 6             Iterator var3 = candidateAdvisors.iterator();
 7
 8             while(var3.hasNext()) {
 9                 Advisor candidate = (Advisor)var3.next();
10                 //第一步: 首先处理  IntroductionAdvisor
11                 if(candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
12                     eligibleAdvisors.add(candidate);
13                 }
14             }
15
16             boolean hasIntroductions = !eligibleAdvisors.isEmpty();
17             Iterator var7 = candidateAdvisors.iterator();
18
19             while(var7.hasNext()) {
20                 Advisor candidate = (Advisor)var7.next();
21                 //第二步: 略过已经处理的 IntroductionAdvisor  并处理普通的 bean
22                 if(!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions)) {
23                     eligibleAdvisors.add(candidate);
24                 }
25             }
26
27             return eligibleAdvisors;
28         }
29     }
 1     public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
 2         //第一步: 处理 IntroductionAdvisor
 3         if(advisor instanceof IntroductionAdvisor) {
 4             return ((IntroductionAdvisor)advisor).getClassFilter().matches(targetClass);
 5         } else if(advisor instanceof PointcutAdvisor) {
 6             //第二步: 处理 普通 bean
 7             PointcutAdvisor pca = (PointcutAdvisor)advisor;
 8             return canApply(pca.getPointcut(), targetClass, hasIntroductions);
 9         } else {
10             return true;
11         }
12     }
 1     public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
 2         Assert.notNull(pc, "Pointcut must not be null");
 3         if(!pc.getClassFilter().matches(targetClass)) {
 4             return false;
 5         } else {
 6             MethodMatcher methodMatcher = pc.getMethodMatcher();
 7             IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
 8             if(methodMatcher instanceof IntroductionAwareMethodMatcher) {
 9                 introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher)methodMatcher;
10             }
11
12             Set<Class<?>> classes = new HashSet(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
13             classes.add(targetClass);
14             Iterator var6 = classes.iterator();
15
16             while(var6.hasNext()) {
17                 Class<?> clazz = (Class)var6.next();
18                 Method[] methods = clazz.getMethods();
19                 Method[] var9 = methods;
20                 int var10 = methods.length;
21                 //第一步: 遍历所有的方法并进行方法匹配
22                 for(int var11 = 0; var11 < var10; ++var11) {
23                     Method method = var9[var11];
24                     if(introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) || methodMatcher.matches(method, targetClass)) {
25                         return true;
26                     }
27                 }
28             }
29
30             return false;
31         }
32     }

, 创建代理

    网上拉,知道看到 wrapIfNecessary() 方法中的第二步, 通过获取的增强器创建代理的 createProxy() 方法, 知道人生这么一天其实也就一个方法而已。。。。 

 1     protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
 2         ProxyFactory proxyFactory = new ProxyFactory();
 3         //第一步: 获取当前类的相关属性
 4         proxyFactory.copyFrom(this);
 5         int var8;
 6         int var9;
 7         if(!this.shouldProxyTargetClass(beanClass, beanName)) {
 8             //第二步:  添加接口
 9             Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
10             Class[] var7 = targetInterfaces;
11             var8 = targetInterfaces.length;
12
13             for(var9 = 0; var9 < var8; ++var9) {
14                 Class<?> targetInterface = var7[var9];
15                 proxyFactory.addInterface(targetInterface);
16             }
17         }
18         //第三步: 加入增强器
19         Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
20         Advisor[] var13 = advisors;
21         var8 = advisors.length;
22
23         for(var9 = 0; var9 < var8; ++var9) {
24             Advisor advisor = var13[var9];
25             proxyFactory.addAdvisor(advisor);
26         }
27         //第四步: 设置要代理的类
28         proxyFactory.setTargetSource(targetSource);
29         //第五步: 使用自己的代理方法
30         this.customizeProxyFactory(proxyFactory);
31         //第六步: 设置代理之后是否允许修改
32         proxyFactory.setFrozen(this.freezeProxy);
33         if(this.advisorsPreFiltered()) {
34             proxyFactory.setPreFiltered(true);
35         }
36         //第七步: 创建代理对象
37         return proxyFactory.getProxy(this.proxyClassLoader);
38     }

    在 createProxy() 方法的第三步中, 在加入增强器之前,需要把 拦截器封装成增强器的实现逻辑:

 1     protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
 2         //第一步: 解析所有注册的 interceptors
 3         Advisor[] commonInterceptors = this.resolveInterceptorNames();
 4         List<Object> allInterceptors = new ArrayList();
 5         if(specificInterceptors != null) {
 6             //第二步: 加入拦截器
 7             allInterceptors.addAll(Arrays.asList(specificInterceptors));
 8             if(commonInterceptors != null) {
 9                 if(this.applyCommonInterceptorsFirst) {
10                     allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
11                 } else {
12                     allInterceptors.addAll(Arrays.asList(commonInterceptors));
13                 }
14             }
15         }
16         int i;
17
18         Advisor[] advisors = new Advisor[allInterceptors.size()];
19
20         for(i = 0; i < allInterceptors.size(); ++i) {
21             //第三步: 拦截器封装为 Advisor
22             advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
23         }
24
25         return advisors;
26     }
 1     public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
 2         //第一步: 若本身已是 Advisor 则直接返回
 3         if(adviceObject instanceof Advisor) {
 4             return (Advisor)adviceObject;
 5         } else if(!(adviceObject instanceof Advice)) {
 6             //第二步: 不是 Advice 或 Advisor 则抛异常
 7             throw new UnknownAdviceTypeException(adviceObject);
 8         } else {
 9             Advice advice = (Advice)adviceObject;
10             if(advice instanceof MethodInterceptor) {
11                 //第三步: 处理 MethodInterceptor 的情况
12                 return new DefaultPointcutAdvisor(advice);
13             } else {
14                 Iterator var3 = this.adapters.iterator();
15                 //第四步: 存在 Advisor 的 adapter 同样封装
16                 AdvisorAdapter adapter;
17                 do {
18                     if(!var3.hasNext()) {
19                         throw new UnknownAdviceTypeException(advice);
20                     }
21
22                     adapter = (AdvisorAdapter)var3.next();
23                 } while(!adapter.supportsAdvice(advice));
24
25                 return new DefaultPointcutAdvisor(advice);
26             }
27         }
28     }

    在 createProxy() 方法中, 根据获取的 Advisor 获取创建代理的 getProxy() 方法的实现逻辑:

1     public Object getProxy(ClassLoader classLoader) {
3         return this.createAopProxy().getProxy(classLoader);
5     }

    首先看看 createAopProxy() 方法的实现:

1     protected final synchronized AopProxy createAopProxy() {
2         if(!this.active) {
3             this.activate();
4         }
5         //第一步:  创建代理
6         return this.getAopProxyFactory().createAopProxy(this);
7     }
 1     public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
 2         //第一步:  1, CGLIB 的优化策略  2, 代理目标类还是目标类的接口    3,是否存在代理接口
 3         if(!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
 4             //第二步: 使用 JDK 动态代理创建
 5             return new JdkDynamicAopProxy(config);
 6         } else {
 7             Class<?> targetClass = config.getTargetClass();
 8             if(targetClass == null) {
 9                 throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
10             } else {
11                 //第三步:  接口吗 ? JDK 动态代理 : CGLIB 创建
12                 return (AopProxy)(targetClass.isInterface()?new JdkDynamicAopProxy(config):new ObjenesisCglibAopProxy(config));
13             }
14         }
15     }

    嘿嘿嘿, 先看看 JDK 动态代理的创建方法, 在 JdkDynamicAopProxy 类中:

1     public Object getProxy(ClassLoader classLoader) {
2         //第一步: 获取接口
3         Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
4         this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
5         //第二步:  创建代理
6         return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
7     }

    查看实现了 InvocationHandler 接口重写的 invoke() 方法:

 1     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 2         Object oldProxy = null;
 3         boolean setProxyContext = false;
 4         TargetSource targetSource = this.advised.targetSource;
 5         Class<?> targetClass = null;
 6         Object target = null;
 7
 8         Object var13;
 9         try {
10             //第一步: 处理 equals 方法
11             if(!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
12                 Boolean var18 = Boolean.valueOf(this.equals(args[0]));
13                 return var18;
14             }
15             //第二步:  处理 hash 方法
16             if(!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
17                 Integer var17 = Integer.valueOf(this.hashCode());
18                 return var17;
19             }
20
21             Object retVal;
22             if(!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
23                 // 第三步: 调用切点方法
24                 retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
25                 return retVal;
26             }
27              //第四步: 之前讲述过的 expose-proxy 属性的情况的处理
28             if(this.advised.exposeProxy) {
29                 oldProxy = AopContext.setCurrentProxy(proxy);
30                 setProxyContext = true;
31             }
32
33             target = targetSource.getTarget();
34             if(target != null) {
35                 targetClass = target.getClass();
36             }
37             //第五歩: 获取方法的拦截器链
38             List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
39             if(chain.isEmpty()) {
40                 //第六步: 拦截器为空 调用切点方法
41                 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
42             } else {
43                 //第七步:  拦截器不为空 封装拦截器并调用方法
44                 MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
45                 retVal = invocation.proceed();
46             }
47             //第八步: 返回结果
48             Class<?> returnType = method.getReturnType();
49             if(retVal != null && retVal == target && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
50                 retVal = proxy;
51             } else if(retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
52                 throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
53             }
54
55             var13 = retVal;
56         } finally {
57             if(target != null && !targetSource.isStatic()) {
58                 targetSource.releaseTarget(target);
59             }
60
61             if(setProxyContext) {
62                 AopContext.setCurrentProxy(oldProxy);
63             }
64
65         }
66
67         return var13;
68     }

    在  JdkDynamicAopProxy 的 invoke()  方法中, 第七步调用拦截器链的 proceed() 实现逻辑, 方法在 ReflectiveMethodInvocation 类中, 从 jdk 又跑回 Spring 中了:

 1     public Object proceed() throws Throwable {
 2         if(this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
 3             return this.invokeJoinpoint();
 4         } else {
 5             //第一步: 获取要执行的下一个拦截器
 6             Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
 7             //第二步:  判断类型
 8             if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
 9                 InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
10                 //第三步:  调用拦截器的方法
11                 return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)?dm.interceptor.invoke(this):this.proceed();
12             } else {
13                 //第四步: 若是普通的拦截器  直接调用方法
14                 return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
15             }
16         }
17     }

    大致了解了 Jdk 创建代理的方法, 下面瞄一下 CGLIB 创建代理的实现方法:

 1     public Object getProxy(ClassLoader classLoader) {
 2         if(logger.isDebugEnabled()) {
 3             logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
 4         }
 5
 6         try {
 7             Class<?> rootClass = this.advised.getTargetClass();
 8             Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
 9             Class<?> proxySuperClass = rootClass;
10             int x;
11             if(ClassUtils.isCglibProxyClass(rootClass)) {
12                 proxySuperClass = rootClass.getSuperclass();
13                 Class<?>[] additionalInterfaces = rootClass.getInterfaces();
14                 Class[] var5 = additionalInterfaces;
15                 int var6 = additionalInterfaces.length;
16
17                 for(x = 0; x < var6; ++x) {
18                     Class<?> additionalInterface = var5[x];
19                     this.advised.addInterface(additionalInterface);
20                 }
21             }
22
23             this.validateClassIfNecessary(proxySuperClass);
24             //第一步:创建 CGLIB 必须的 Enchancer 并为其设置属性
25             Enhancer enhancer = this.createEnhancer();
26             if(classLoader != null) {
27                 enhancer.setClassLoader(classLoader);
28                 if(classLoader instanceof SmartClassLoader && ((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass)) {
29                     enhancer.setUseCache(false);
30                 }
31             }
32
33             enhancer.setSuperclass(proxySuperClass);
34             enhancer.setStrategy(new MemorySafeUndeclaredThrowableStrategy(UndeclaredThrowableException.class));
35             enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
36             //第二步: 为 enchancer 设置 拦截器
37             Callback[] callbacks = this.getCallbacks(rootClass);
38             Class<?>[] types = new Class[callbacks.length];
39
40             for(x = 0; x < types.length; ++x) {
41                 types[x] = callbacks[x].getClass();
42             }
43
44             enhancer.setCallbackTypes(types);
45             enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
46             //第三步: 生成代理及创建代理类
47             return this.createProxyClassAndInstance(enhancer, callbacks);
48         }
49     }

    为 enchancer 设置拦截器的 getCallbacks() 方法的实现逻辑:

 1     private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
 2         //第一步:  对于 expose-proxy 属性的处理
 3         boolean exposeProxy = this.advised.isExposeProxy();
 4         boolean isFrozen = this.advised.isFrozen();
 5         boolean isStatic = this.advised.getTargetSource().isStatic();
 6         //第二步:  封装 DynamicAdvisedInterceptor
 7         Callback aopInterceptor = new CglibAopProxy.DynamicAdvisedInterceptor(this.advised);
 8         Object targetInterceptor;
 9         if(exposeProxy) {
10             targetInterceptor = isStatic?new CglibAopProxy.StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()):new CglibAopProxy.DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
11         } else {
12             targetInterceptor = isStatic?new CglibAopProxy.StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()):new CglibAopProxy.DynamicUnadvisedInterceptor(this.advised.getTargetSource());
13         }
14
15         Callback targetDispatcher = (Callback)(isStatic?new CglibAopProxy.StaticDispatcher(this.advised.getTargetSource().getTarget()):new CglibAopProxy.SerializableNoOp());
16         //第三步: 加入拦截器
17         Callback[] mainCallbacks = new Callback[]{aopInterceptor, (Callback)targetInterceptor, new CglibAopProxy.SerializableNoOp(), targetDispatcher, this.advisedDispatcher, new CglibAopProxy.EqualsInterceptor(this.advised), new CglibAopProxy.HashCodeInterceptor(this.advised)};
18         Callback[] callbacks;
19         if(isStatic && isFrozen) {
20             Method[] methods = rootClass.getMethods();
21             Callback[] fixedCallbacks = new Callback[methods.length];
22             this.fixedInterceptorMap = new HashMap(methods.length);
23
24             for(int x = 0; x < methods.length; ++x) {
25                 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
26                 fixedCallbacks[x] = new CglibAopProxy.FixedChainStaticTargetInterceptor(chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
27                 this.fixedInterceptorMap.put(methods[x].toString(), Integer.valueOf(x));
28             }
29
30             callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
31             System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
32             System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
33             this.fixedInterceptorOffset = mainCallbacks.length;
34         } else {
35             callbacks = mainCallbacks;
36         }
37
38         return callbacks;
39     }

    (? _ ?) 神 TMD 的什么鬼, 看不懂啊 。。。。

    在 CGLIB 中, 用  DynamicAdvisedInterceptor  封装了 增强器,查看该类中的 intercept() 方法:

 1         public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
 2             Object oldProxy = null;
 3             boolean setProxyContext = false;
 4             Class<?> targetClass = null;
 5             Object target = null;
 6
 7             Object var11;
 8             try {
 9                 if(this.advised.exposeProxy) {
10                     oldProxy = AopContext.setCurrentProxy(proxy);
11                     setProxyContext = true;
12                 }
13
14                 target = this.getTarget();
15                 if(target != null) {
16                     targetClass = target.getClass();
17                 }
18
19                 //第一步: 获取拦截器你链
20                 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
21                 Object retVal;
22                 if(chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
23                     //第二步: 拦截器为空则直接调用原方法
24                     retVal = methodProxy.invoke(target, args);
25                 } else {
26                     //第三步:  拦截器不为空则调用链
27                     retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
28                 }
29                 //第四步: 改变返回值的类型并 返回结果
30                 retVal = CglibAopProxy.processReturnType(proxy, target, method, retVal);
31                 var11 = retVal;
32             } finally {
33                 if(target != null) {
34                     this.releaseTarget(target);
35                 }
36
37                 if(setProxyContext) {
38                     AopContext.setCurrentProxy(oldProxy);
39                 }
40
41             }
42
43             return var11;
44         }

    看到返回结果之后,我们就大致了(bu)解(dong)了 CGLIB 的运行流程了。 (? _ ?)



    本来想把 Spring AOP 中动态 AOP 和静态 AOP 的运行流程都大致回顾一遍的, 但是回顾了动态 AOP 的内容之后, 感觉还是有很多不懂的地方, 接下去不常用的静态 AOP 的内容会是瞎蒙吧, 以后深入了解后再把没做的部分完成吧。 Spring 的源码很多, 想学深不简单, 加油!![]~( ̄▽ ̄)~*

时间: 2024-10-11 17:11:55

Spring源码学习笔记(7)的相关文章

Spring源码学习笔记(6)

Spring源码学习笔记(六) 前言-- 最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门. 上一篇中我们梳理到 Spring 加载 XML 配置文件, 完成 XML 的解析工作,接下来我们将进入 Spring 加载 bean 的逻辑. 我们使用 Spring 获取 XML

Spring源码学习笔记(3)

Spring源码学习笔记(三) 前言----     最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门. DispatcherServlet 实现核心功能 和普通的 Servelt 类一样, DispatcherServlet 中的 doGet() 和 doPost() 方法

Spring源码学习笔记(5)

Spring源码学习笔记(五) 前言-- 最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门 写下一句话,开篇不尴尬  ----  上篇文章中梳理到 Spring 加载资源文件后开始解析 Bean, 现在我们从两个解析函数 parseDefaultElement() 和 par

Spring源码学习笔记(1)

SpringMVC源码学习笔记(一) 前言----   最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门.  进入正文,首先贴上SpringMVC的图片(来自https://docs.spring.io/spring/docs/current/spring-framework

Spring源码学习笔记1

1.Spring中最核心的两个类 1)DefaultListableBeanFactory XmlBeanFactory继承自DefaultListableBeanFactory,DefaultListableBeanFactory是整个bean加载的核心部分,是Spring加载及注册bean的默认实现 2)XmlBeanDefinitionReader 2.示例代码 BeanFactory bf=new XmlBeanFactory(new ClassPathResource("beanFac

Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件

写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设计精巧,代码优美,值得每一名开发人员学习阅读. 在我最开始学习javaEE时,第一次接触Spring是从一个S(Struts)S(Spring)H(Herbinate)的框架开始.由java原生开发到框架开发转换过程中,那时我的印象里Struts负责控制层,herbinate负责数据层,而Sprin

Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类

Hadoop源码学习笔记(1) ——找到Main函数及读一读Configure类 前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用.在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何实现的. 提前申明,本人是一直搞.net的,对java略为生疏,所以在学习该作品时,会时不时插入对java的学习,到时也会摆一些上来,包括一下设计模式之类的.欢迎高手指正. 整个学习过程,我们主要通过eclipse来学习,之前已经讲过如何在eclipse中搭建调试环境,这里就不多述了. 在之前源码初

Hadoop源码学习笔记(4) ——Socket到RPC调用

Hadoop源码学习笔记(4) ——Socket到RPC调用 Hadoop是一个分布式程序,分布在多台机器上运行,事必会涉及到网络编程.那这里如何让网络编程变得简单.透明的呢? 网络编程中,首先我们要学的就是Socket编程,这是网络编程中最底层的程序接口,分为服务器端和客户端,服务器负责监听某个端口,客户端负责连接服务器上的某个端口,一旦连接通过后,服务器和客户端就可以双向通讯了,我们看下示例代码: ServerSocket server = new ServerSocket(8111); S

Hadoop源码学习笔记(3) ——初览DataNode及学习线程

Hadoop源码学习笔记(3) ——初览DataNode及学习线程 进入了main函数,我们走出了第一步,接下来看看再怎么走: public class DataNode extends Configured implements InterDatanodeProtocol,       ClientDatanodeProtocol, FSConstants, Runnable {      public static DataNode createDataNode(String args[],