本文主要針對註解形式的AOP作分析,即在application.xml適用<aop:aspectj-autoproxy />
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);
這裏不做源碼分析了。