在xml定义的Aop相关的bean一般是像这样:
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="afterUpdateBlHandler" class="com.citic.sggljg.ctrl.xxjg.AfterUpdateBlHandler"/>
<aop:config >
<aop:pointcut id="pointCutMethods" expression="execution(* com.citic.sggljg.ctrl.xxjg.Jgyj*.update(..))" />
<aop:aspect id="aspect_afterupdate" ref="afterUpdateBlHandler" >
<aop:after method="afterUpdate" pointcut-ref="pointCutMethods" />
<aop:before method=""/>
</aop:aspect>
</aop:config>
在java类中的各个标签对应的解析类如图:
下面我们就依次解析各个标签。
- aop:aspectj-autoproxy
这个标签的配置一般是这样的<aop:aspectj-autoproxy proxy-target-class="true"/>
。对应的解析类是AspectJAutoProxyBeanDefinitionParser,下面的重点就是研究这个类源码。
代码很简单,就是往bean工厂注册一个类AnnotationAwareAspectJAutoProxyCreator,在工厂中的名称是org.springframework.aop.config.internalAutoProxyCreator。
public BeanDefinition parse(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
extendBeanDefinition(element, parserContext);
return null;
}
- aop:config
对应的解析类是ConfigBeanDefinitionParser,看具体的解析过程:
public BeanDefinition parse(Element element, ParserContext parserContext) {
CompositeComponentDefinition compositeDef =
new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compositeDef);
//注册AspectJAwareAdvisorAutoProxyCreator到工厂
configureAutoProxyCreator(parserContext, element);
List<Element> childElts = DomUtils.getChildElements(element);
for (Element elt: childElts) {//得到子类标签 <aop:pointcut
String localName = parserContext.getDelegate().getLocalName(elt);
// <aop:pointcut id="txPointcut" expression="execution(* cn.javass..service..*.*(..))" />
//会将上面的标签解析为 AspectJExpressionPointcut 类的切口
if (POINTCUT.equals(localName)) {
parsePointcut(elt, parserContext);
}
// <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
//解析为DefaultBeanFactoryPointcutAdvisor对象
else if (ADVISOR.equals(localName)) {
parseAdvisor(elt, parserContext);
}
else if (ASPECT.equals(localName)) {
parseAspect(elt, parserContext);
}
}
parserContext.popAndRegisterContainingComponent();
return null;
}