About register aspect jannationautoproxycreator if necessary of AopNamespaceUtils

Keywords: JDK Attribute Spring

About this method

public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
            ParserContext parserContext, Element sourceElement) {
        //1. Register or upgrade creator definition beanname
        BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
                parserContext.getRegistry(), parserContext.extractSource(sourceElement));
        //2. Processing of proxy tartarget class and expose proxy attributes      
        useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
        //3. Register components and notify for further processing by the listener
        registerComponentIfNecessary(beanDefinition, parserContext);
    }

These three steps
//*********************************************************************************
First step
He can automatically match the proxy Bean according to the pointcut defined by the @ Point annotation
For the implementation of Aop, annotation aware spectjauto proxycreator is basically used
The registration process is implemented here

@Nullable
    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
            @Nullable Object source) {

        return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    }

Method jump

@Nullable
    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
            @Nullable Object source) {

        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        //If there is already an automatic agent creator and it is inconsistent with the current one, you need to judge the priority
        if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
            BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
            //Creator inconsistent
            if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            //Priority existing for current priority
                int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
                //Current priority
                int requiredPriority = findPriorityForClass(cls);
                //Higher value, lower priority  
                if (currentPriority < requiredPriority) {
                    apcDefinition.setBeanClassName(cls.getName());
                }
            }
            //If there is a creator and a value to be created
            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;
    }

In the above code, the function of automatically registering the creator class is implemented, and there is also a priority problem.

//**************************************************************************************
The second step
Use class proxying if necessary
Implement the attribute processing of proxy target class and expose proxy

private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, @Nullable Element sourceElement) {
        if (sourceElement != null) {
            boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
            //If it is a targetclass proxy target class
            if (proxyTargetClass) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            //If it's expose
            boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
            if (exposeProxy) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }

The process of mandatory use is a process of property setting

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

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

The proxy target class spring AOP section uses the JDK proxy or CGLIB to create a proxy for the target object.
It is recommended to try to JDK agent

Only CGLIB proxy can be used when there is no interface method.

Disadvantages of cglib agent:
The final method cannot be notified because it cannot be overridden
Related packages need to be introduced

cglib forces the proxy target class property of to true

cglib agent can generate the target class subclass during running, and the underlying layer has strong performance depending on the asm library operation bytecode.

Sometimes the self calling of the target object will fail to implement the facet enhancement.
I didn't understand this property myself.

//***********************************************
The third step
Register components and notify for further processing by the listener

private static void registerComponentIfNecessary(@Nullable BeanDefinition beanDefinition, ParserContext parserContext) {
        if (beanDefinition != null) {
            BeanComponentDefinition componentDefinition =
                    new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
            parserContext.registerComponent(componentDefinition);
        }
    }

Posted by Grizzzzzzzzzz on Mon, 13 Apr 2020 09:50:16 -0700