spring源码分析之spring注解@Aspect是如何工作的?

本文详细介绍了Spring中如何通过@AspectJ注解实现面向切面编程(AOP),包括配置解析、代理创建及实现类的工作流程。深入探讨了AnnotationAwareAspectJAutoProxyCreator的作用及其在Spring框架中的注册和使用过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值