Spring AOP的实现原理之<aop:aspectj-autoproxy />的解析

本文主要针对注解形式的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);  
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值