Spring AOP的實現原理之的解析


本文主要針對註解形式的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);

這裏不做源碼分析了。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章