zoukankan      html  css  js  c++  java
  • spring源码分析之spring注解@Aspect是如何工作的?

    1、@Aspect

       在xml定义:<aop:aspectj-autoproxy />,其定义在http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

    - <xsd:element name="aspectj-autoproxy">
    - <xsd:annotation>
    - <xsd:documentation source="java:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator">
    - <![CDATA[ 
        Enables the use of the @AspectJ style of Spring AOP.
                
    
      ]]> 
      </xsd:documentation>
      </xsd:annotation>
    - <xsd:complexType>
    - <xsd:sequence>
    - <xsd:element name="include" type="includeType" minOccurs="0" maxOccurs="unbounded">
    - <xsd:annotation>
    - <xsd:documentation>
    - <![CDATA[ 
        Indicates that only @AspectJ beans with names matched by the (regex)
        pattern will be considered as defining aspects to use for Spring autoproxying.
                            
    
      ]]> 
      </xsd:documentation>
      </xsd:annotation>
      </xsd:element>
      </xsd:sequence>
    - <xsd:attribute name="proxy-target-class" type="xsd:boolean" default="false">
    - <xsd:annotation>
    - <xsd:documentation>
    - <![CDATA[ 
        Are class-based (CGLIB) proxies to be created? By default, standard
        Java interface-based proxies are created.
                        
    
      ]]> 
      </xsd:documentation>
      </xsd:annotation>
      </xsd:attribute>
    - <xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
    - <xsd:annotation>
    - <xsd:documentation>
    - <![CDATA[ 
        Indicate that the proxy should be exposed by the AOP framework as a
        ThreadLocal for retrieval via the AopContext class. Off by default,
        i.e. no guarantees that AopContext access will work.
                        
    
      ]]> 
      </xsd:documentation>
      </xsd:annotation>
      </xsd:attribute>
      </xsd:complexType>
      </xsd:element>

    1.1 注册

    org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator

     的继承关系如下:

    1.2 解析过程

    AspectJAutoProxyBeanDefinitionParser.java#parse()方法

        public BeanDefinition parse(Element element, ParserContext parserContext) {
            AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
            extendBeanDefinition(element, parserContext);
            return null;
        }

    注册过程:

        public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
                ParserContext parserContext, Element sourceElement) {
    
            BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
                    parserContext.getRegistry(), parserContext.extractSource(sourceElement));
            useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
            registerComponentIfNecessary(beanDefinition, parserContext);
        }

    调用实现类:

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

    1.3 具体实现类为:AbstractAutoProxyCreator的postProcessAfterInitialization()方法

    DefaultAopProxyFactory#createAopProxy()方法

    @Override
        public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
            if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
                Class<?> targetClass = config.getTargetClass();
                if (targetClass == null) {
                    throw new AopConfigException("TargetSource cannot determine target class: " +
                            "Either an interface or a target is required for proxy creation.");
                }
                if (targetClass.isInterface()) {
                    return new JdkDynamicAopProxy(config);
                }
                return new ObjenesisCglibAopProxy(config);
            }
            else {
                return new JdkDynamicAopProxy(config);
            }
        }

    默认使用jdk自带的代理,还有一种cglib方式。

  • 相关阅读:
    mybatis和spring整合
    Freemarker教程1(基本使用)
    mybatis教程6(逆向工程)
    mybatis教程4(动态SQL)
    mybatis教程5(延迟加载和缓存)
    mybatis教程2(配置文件)
    python作用域
    软件测试基础面试题
    http协议
    selenium自动化测试
  • 原文地址:https://www.cnblogs.com/davidwang456/p/5633940.html
Copyright © 2011-2022 走看看