本文主要针对注解形式的AOP作分析,即在application.xml适用<aop:aspectj-autoproxy />
当Spring 解析application.xml遇到上面提及的aop标签,而这个标签属于自定义标签,
DefaultBeanDefinitionDocumentReader 委托delegate处理自定义标签
/**
* Parse the elements at the root level in the document:
* "import", "alias", "bean".
* @param root the DOM root element of the document
*/
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
delegate.parseCustomElement(root);
这句代码也就在META-INF文件下找到spring.handlers中ele所对应命名空间的handler,并在init()函数注册AspectJAutoProxyBeanDefinitionParser
BeanDefinitionParserDelegate
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(ele);
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
AopNamespacceHandler
public 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());
}
handler.parse()代码逻辑最后会调用到AspectJAutoProxyBeanDefinitionParser.parse()
AspectJAutoProxyBeanDefinitionParser
public BeanDefinition parse(Element element, ParserContext parserContext) {
//注册或者升级name="org.springframework.aop.config.internalAutoProxyCreator"的bean
//并且处理proxy-target-class以及expose-proxy属性
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
extendBeanDefinition(element, parserContext);
return null;
}
到目前为止就完成了<aop:aspectj-autoproxy />的解析。
顺便提及下proxy-target-class属性若此值为true强制使用CGLIB代理;expose-proxy属性是为了目标对象内部的自我调用无法实施切面中增加
具体的阔以跟踪
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
这里不做源码分析了。