写在后面
最近,不少小伙伴在催更【Spring注解驱动开发】专题,好吧,【Spring注解驱动开发】专题的确有很长时间没更新了。那咱们从明天开始更新【Spring注解驱动开发】专题,同样的,咱们还是以源码解析为主。文章已同步收录到:https://github.com/sunshinelyz/technology-binghe 和 https://gitee.com/binghe001/technology-binghe 。如果文件对你有点帮忙,别忘记给个Star哦!
关注【冰河技术】微信公众号,回复“Spring注解”支付工程源码。
类结构图
咱们先来看下AnnotationAwareAspectJAutoProxyCreator类的结构图。
上图中一些 类/接口 的介绍:
AspectJAwareAdvisorAutoProxyCreator : 公开了AspectJ的调用上下文,并弄清楚来自同所有面的多个Advisor在AspectJ中的优先级规定。
AbstractAdvisorAutoProxyCreator : 通用主动代理创立器,它基于检测到的每个参谋程序为特定bean构建AOP代理。
AbstractAutoProxyCreator : 扩大了 ProxyProcessorSupport,实现了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口,是BeanPostProcessor 实现,该实现应用AOP代理包装每个合格的bean,并在调用bean自身之前委派给指定的拦截器。
BeanFactoryAware : 实现了该接口的Bean能够晓得它属于那个 BeanFactory,Bean能够通过Spring容器查找它的协同者(依赖查找),但大多数的Bean是通过结构器参数和Bean办法(依赖注入)来获取它的协同者。
BeanPostProcessor :工厂钩子,容许自定义批改新的bean实例。例如,查看标记接口或应用代理包装bean。如果咱们须要在Spring容器中实现Bean的实例化,配置和其初始化前后增加一些本人的逻辑解决,咱们就能够定义一个或多个BeanPostProcessor接口的实现,而后注册到容器中。
InstantiationAwareBeanPostProcessor : BeanPostProcessor 的子接口,它增加了实例化之前的回调,以及实例化之后但设置了显式属性或主动拆卸之前的回调。它外部提供了3个办法,再加上BeanPostProcessor接口外部的2个办法,实现这个接口须要实现5个办法。InstantiationAwareBeanPostProcessor 接口的次要作用在于指标对象的实例化过程中须要解决的事件,包含实例化对象的前后过程以及实例的属性设置。
SmartInstantiationAwareBeanPostProcessor : InstantiationAwareBeanPostProcessor 接口的扩大,多出了3个办法,增加了用于预测已解决bean的最终类型的回调,再加上父接口的5个办法,所以实现这个接口须要实现8个办法,次要作用也是在于指标对象的实例化过程中须要解决的事件。
总之:AspectJAwareAdvisorAutoProxyCreator为 AspectJ 切面类创立主动代理。
外围类解析
BeanPostProcessor 接口中的两个办法 postProcessBeforeInitialization 和 postProcessAfterInitialization,作用是对Bean初始化前后增加一些本人的逻辑。
@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean;}@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean;}
InstantiationAwareBeanPostProcessor 是 BeanPostProcessor 的子接口,它额定减少了3个新的办法:postProcessBeforeInstantiation( 指标对象被实例化之前调用的办法,能够返回指标实例的一个代理用来代替指标实例 )、postProcessAfterInstantiation(该办法在Bean实例化之后执行,返回false,会疏忽属性值的设置;如果返回true,会依照失常流程设置属性值) 和 postProcessPropertyValues(对属性值进行批改,将来版本将会删除)
@Nullabledefault Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null;}default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true;}@Nullabledefault PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs;}
SmartInstantiationAwareBeanPostProcessor接口继承InstantiationAwareBeanPostProcessor接口,外面定义了3个办法:predictBeanType(预测Bean的类型)、determineCandidateConstructors(抉择适合的结构器)、getEarlyBeanReference(解决循环援用问题)。
@Nullabledefault Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException { return null;}@Nullabledefault Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException { return null;}default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { return bean;}
AbstractAutoProxyCreator 是AOP的一个外围类,它实现了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口,实现了代理创立的逻辑,应用AOP代理包装每个合格的bean,并在调用bean自身之前委派给指定的拦截器。
AbstractAdvisorAutoProxyCreator 通用主动代理创立器,它基于检测每个bean的增强器,为非凡的bean构建AOP代理。子类能够重写此findCandidateAdvisors()办法,以返回实用于任何对象的advisor的自定义列表,子类还能够重写继承的AbstractAutoProxyCreator.shouldSkip()办法,以将某些对象排除在主动代理之外。
protected List<Advisor> findCandidateAdvisors() { Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available"); return this.advisorRetrievalHelper.findAdvisorBeans();}
AspectJAwareAdvisorAutoProxyCreator 扩大 AbstractAdvisorAutoProxyCreator,公开了AspectJ的调用上下文,并在多个增强器来自同所有面时搞清楚AspectJ的倡议优先级程序。按AspectJ优先级排序其余部分:
@Override@SuppressWarnings("unchecked")protected List<Advisor> sortAdvisors(List<Advisor> advisors) { List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors = new ArrayList<>(advisors.size()); for (Advisor element : advisors) { partiallyComparableAdvisors.add( new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR)); } List<PartiallyComparableAdvisorHolder> sorted = PartialOrder.sort(partiallyComparableAdvisors); if (sorted != null) { List<Advisor> result = new ArrayList<>(advisors.size()); for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) { result.add(pcAdvisor.getAdvisor()); } return result; } else { return super.sortAdvisors(advisors); }}
在加强链头部减少一个ExposeInvocationInterceptor,应用AspectJ表达式切入点和应用AspectJ款式的advisor时,须要这些附加advisor。
protected void extendAdvisors(List<Advisor> candidateAdvisors) { AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);}
如果尔后处理器不应该思考将给定的bean用于主动代理,子类应重写此办法以返回true
@Overrideprotected boolean shouldSkip(Class<?> beanClass, String beanName) { // TODO: Consider optimization by caching the list of the aspect names List<Advisor> candidateAdvisors = findCandidateAdvisors(); for (Advisor advisor : candidateAdvisors) { if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { return true; } } return super.shouldSkip(beanClass, beanName);}
AspectJAwareAdvisorAutoProxyCreator 还有一个子类叫 AnnotationAwareAspectJAutoProxyCreator,子类AnnotationAwareAspectJAutoProxyCreator是用于解决以后应用程序上下文中的所有AspectJ正文方面以及Spring Advisor。如果Spring AOP的基于代理的模型可能利用任何AspectJ正文的类,它们的advisor将被自动识别,这涵盖了办法执行连接点,Spring Advisor的解决遵循AbstractAdvisorAutoProxyCreator中建设的规定。
生成代理对象
从应用<aop:xxx>标签来主动生成代理的话,先看看AopNamespaceHandler,应用<aop:config>标签则应用 ConfigBeanDefinitionParser 解析,应用了<aop:aspectj-autoproxy>标签则应用 AspectJAutoProxyBeanDefinitionParser 解析,顺次类推。
@Overridepublic void init() { // In 2.0 XSD as well as in 2.1 XSD. registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser()); registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser()); registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator()); // Only in 2.0 XSD: moved to context namespace as of 2.1 registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());}
- <aop:config>形式应用 AspectJAwareAdvisorAutoProxyCreator 创立代理
- <aop:aspectj-autoproxy>应用 AnnotationAwareAspectJAutoProxyCreator 创立代理
ConfigBeanDefinitionParser.java
@Override@Nullablepublic BeanDefinition parse(Element element, ParserContext parserContext) { CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element)); parserContext.pushContainingComponent(compositeDef); configureAutoProxyCreator(parserContext, element); // 注册AspectJAwareAdvisorAutoProxyCreator List<Element> childElts = DomUtils.getChildElements(element); for (Element elt: childElts) { String localName = parserContext.getDelegate().getLocalName(elt); if (POINTCUT.equals(localName)) { parsePointcut(elt, parserContext); } else if (ADVISOR.equals(localName)) { parseAdvisor(elt, parserContext); } else if (ASPECT.equals(localName)) { parseAspect(elt, parserContext); } } parserContext.popAndRegisterContainingComponent(); return null;}private void configureAutoProxyCreator(ParserContext parserContext, Element element) { AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);}
AopConfigUtils.java
@Override@Nullablepublic BeanDefinition parse(Element element, ParserContext parserContext) { CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element)); parserContext.pushContainingComponent(compositeDef); configureAutoProxyCreator(parserContext, element); // 注册AspectJAwareAdvisorAutoProxyCreator List<Element> childElts = DomUtils.getChildElements(element); for (Element elt: childElts) { String localName = parserContext.getDelegate().getLocalName(elt); if (POINTCUT.equals(localName)) { parsePointcut(elt, parserContext); } else if (ADVISOR.equals(localName)) { parseAdvisor(elt, parserContext); } else if (ASPECT.equals(localName)) { parseAspect(elt, parserContext); } } parserContext.popAndRegisterContainingComponent(); return null;}private void configureAutoProxyCreator(ParserContext parserContext, Element element) { AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);}
AopConfigUtils.java
public static void registerAspectJAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) { // 在这里注册的是AspectJAwareAdvisorAutoProxyCreator BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); registerComponentIfNecessary(beanDefinition, parserContext); // 注册组件}
@Nullablepublic static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);}
AspectJAwareAdvisorAutoProxyCreator 实现了 BeanPostProcessor 等下面介绍的接口,次要作用于Bean初始化前后,实例化前后,所有的Bean都被作用到。InstantiationAwareBeanPostProcessor 是 BeanPostProcessor的子接口,但它的调用工夫点产生在Bean实例化前,在真正调用doCreateBean()创立bean实例之前执行postProcessBeforeInstantiation()。
AbstractAutoProxyCreator.java
@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { Object cacheKey = getCacheKey(beanClass, beanName); // 失去一个缓存的惟一key(依据beanClass和beanName生成惟一key) // 如果以后targetSourcedBeans(通过自定义TargetSourceCreator创立的TargetSource)不蕴含cacheKey if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { //advisedBeans(曾经被加强的Bean,即AOP代理对象)中蕴含以后cacheKey,返回null,即走Spring默认流程 return null; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {// 如果是基础设施类(如Advisor、Advice、AopInfrastructureBean的实现)不进行解决;(略) this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } // 如果有自定义的TargetSource,在此处创立代理 // 禁止指标Bean的不必要的默认实例化: // TargetSource将以自定义形式解决指标实例。 TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } return null;}
通过 AbstractAutoProxyCreator 中的 postProcessAfterInitialization() 创立AOP代理。
@Overridepublic Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { // 如果之前调用过getEarlyBeanReference获取包装指标对象到AOP代理对象(如果须要),则不再执行 return wrapIfNecessary(bean, beanName, cacheKey); // 包装指标对象到AOP代理对象(如果须要) } } return bean;}protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { // 通过TargetSourceCreator进行自定义TargetSource不须要包装 return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { // 不应该被加强对象不须要包装 return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { // 基础设施或应该skip的不须要保障 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // 如果有advise则创立代理。 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); // 创立代理对象 this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean;}
好了,明天就到这儿吧,我是冰河,咱们下期见~~
重磅福利
微信搜一搜【冰河技术】微信公众号,关注这个有深度的程序员,每天浏览超硬核技术干货,公众号内回复【PDF】有我筹备的一线大厂面试材料和我原创的超硬核PDF技术文档,以及我为大家精心筹备的多套简历模板(不断更新中),心愿大家都能找到心仪的工作,学习是一条时而郁郁寡欢,时而开怀大笑的路,加油。如果你通过致力胜利进入到了心仪的公司,肯定不要懈怠放松,职场成长和新技术学习一样,逆水行舟。如果有幸咱们江湖再见!
另外,我开源的各个PDF,后续我都会继续更新和保护,感激大家长期以来对冰河的反对!!