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);

这里不做源码分析了。

    原文作者:AOP
    原文地址: https://blog.csdn.net/yoxibaga/article/details/23467781
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞