Spring系列之AOP(2)——aspectj-autoproxy标签注入AnnotationAwareAspectJAutoProxyCreator

1、时序图

Spring系列之AOP(2)——aspectj-autoproxy标签注入AnnotationAwareAspectJAutoProxyCreator_第1张图片
图片.png

流程说明
1)AOP标签的定义解析刘彻骨肯定是从NamespaceHandlerSupport的实现类开始解析的,这个实现类就是AopNamespaceHandler。至于为什么会是从NamespaceHandlerSupport的实现类开始解析的,这个的话我想读者可以去在回去看看Spring自定义标签的解析流程,里面说的比较详细。

2)要启用AOP,我们一般会在Spring里面配置 ,所以在配置文件中在遇到aspectj-autoproxy标签的时候我们会采用AspectJAutoProxyBeanDefinitionParser解析器

3)进入AspectJAutoProxyBeanDefinitionParser解析器后,调用AspectJAutoProxyBeanDefinitionParser已覆盖BeanDefinitionParser的parser方法,然后parser方法把请求转交给了AopNamespaceUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary去处理

4)进入AopNamespaceUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法后,先调用AopConfigUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法,里面在转发调用给registerOrEscalateApcAsRequired,注册或者升级AnnotationAwareAspectJAutoProxyCreator类。对于AOP的实现,基本是靠AnnotationAwareAspectJAutoProxyCreator去完成的,它可以根据@point注解定义的切点来代理相匹配的bean。

5)AopConfigUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法处理完成之后,接下来会调用useClassProxyingIfNecessary() 处理proxy-target-class以及expose-proxy属性。如果将proxy-target-class设置为true的话,那么会强制使用CGLIB代理,否则使用jdk动态代理,expose-proxy属性是为了解决有时候目标对象内部的自我调用无法实现切面增强。

6)最后的调用registerComponentIfNecessary 方法,注册组建并且通知便于监听器做进一步处理。

2、代码解析

aspectj-autoproxy标签
注册AspectJAutoProxyBeanDefinitionParser

public class AopNamespaceHandler extends NamespaceHandlerSupport {
 
    /**
     * Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
     * '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}'
     * and '{@code scoped-proxy}' tags.
     */
    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());
    }
 
}

//AspectJAutoProxyBeanDefinitionParser实现BeanDefinitionParser接口,parse方法作为接口的入口。

class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
 
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
        //对于注解中子类的处理
        extendBeanDefinition(element, parserContext);
        return null;
    }
 
    private void extendBeanDefinition(Element element, ParserContext parserContext) {
        BeanDefinition beanDef =
                parserContext.getRegistry().getBeanDefinition(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
        if (element.hasChildNodes()) {
            addIncludePatterns(element, parserContext, beanDef);
        }
    }
 
    private void addIncludePatterns(Element element, ParserContext parserContext, BeanDefinition beanDef) {
        ManagedList includePatterns = new ManagedList();
        NodeList childNodes = element.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node node = childNodes.item(i);
            if (node instanceof Element) {
                Element includeElement = (Element) node;
                TypedStringValue valueHolder = new TypedStringValue(includeElement.getAttribute("name"));
                valueHolder.setSource(parserContext.extractSource(includeElement));
                includePatterns.add(valueHolder);
            }
        }
        if (!includePatterns.isEmpty()) {
            includePatterns.setSource(parserContext.extractSource(element));
            beanDef.getPropertyValues().add("includePatterns", includePatterns);
        }
    }
 
}

AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary方法注册

public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
            ParserContext parserContext, Element sourceElement) {
 
        // 注册或升级AutoProxyCreator 定义beanName 为          
         //org.Springframework.aop.config.internalAutoProxyCreator 的BeanDefinition
        BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
                parserContext.getRegistry(), parserContext.extractSource(sourceElement));
        // 对于proxy-target-class 以及expose-proxy属性的处理
        useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
        registerComponentIfNecessary(beanDefinition, parserContext);
}

//AopNamespaceUtils类的useClassProxyingIfNecessary方法
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
        if (sourceElement != null) {
            boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
            if (proxyTargetClass) {//类代理
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
            if (exposeProxy) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
}

AopConfigUtils类,注册AnnotationAwareAspectJAutoProxyCreator类

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
        return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
 

private static BeanDefinition registerOrEscalateApcAsRequired(Class cls, BeanDefinitionRegistry registry, Object source) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
            BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
            if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
                int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
                int requiredPriority = findPriorityForClass(cls);
                if (currentPriority < requiredPriority) {
                    apcDefinition.setBeanClassName(cls.getName());
                }
            }
            return null;
        }
        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
        beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
        return beanDefinition;
}

//AopConfigUtils类,对于proxy-target-class属性的处理
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
        if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
            BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
            definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
        }
}

//AopConfigUtils类,对于expose-proxy属性的处理 
static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
        if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
            BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
            definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
        }
 }

·proxy-target-class:Spring AOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理。(建议尽量使用JDK的动态代理),如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理。所有该目标类型实现的接口都将被代理。若该目标对象没有实现任何接口,则创建一个CGLIB代理。如果你希望强制使用CGLIB代理,(例如希望代理目标对象的所有方法,而不只是实现自接口的方法)那也可以。但是需要考虑以下两个问题。
•无法通知(advise)Final方法,因为它们不能被覆写。
•你需要将CGLIB二进制发行包放在classpath下面。
与之相较,JDK本身就提供了动态代理,强制使用 CGLIB代理需要将 的proxy-target-class属性设为true:
...
当需要使用CGLIB代理和@AspectJ自动代理支持,可以按照以下方式设置的proxy-target-class属性:

你可能感兴趣的:(Spring系列之AOP(2)——aspectj-autoproxy标签注入AnnotationAwareAspectJAutoProxyCreator)