Spring源码学习笔记

Posted DarkFuture

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring源码学习笔记相关的知识,希望对你有一定的参考价值。

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() 实现逻辑: