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() 实现逻辑:
1以上是关于Spring源码学习笔记的主要内容,如果未能解决你的问题,请参考以下文章
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段