Spring和AOP的集成与原理实现

目录

一、AOP简介

二、AspectJ源码解析

1.代码示例

1.1 aspect类:

1.2 Maven:

1.3 applicatioin.xml

2.AOP结构组成

3.源码分析

3.1 AnnotationAwareAspectJAutoProxyCreator类注入流程

3.2 spring刷新上下文的调用入口

3.3 DefaultListableBeanFactory类

3.4 AbstractAutoProxyCreator类

4.springboot对AOP的自动集成

4.1 AopAutoConfiguration类

4.2 EnableAspectJAutoProxy注解

4.3 AspectJAutoProxyRegistrar类


一、AOP简介

AOP指的是Aspect Object Programing,即切面对象编程,大致意思是如果原来的流程是12345顺序执行的,使用了AOP之后,可以变成12a34b5的执行流程,而a和b操作便是使用AOP进行额外的操作,例如日志打印、性能测试、权限校验、事务管理和功能加强等。

其实现原理便是采用代理模式,而我们知道代理模式的实现一共分为三种:

  1. 静态代理模式:使用代码写死代理对象,为最基础的实现方式,比较死板;
  2. JDK动态代理模式:实现JDK提供的InvocationHandler接口,在invoke方法中加入需要额外实现的功能便可完成代理模式。本质上是使用反射实现且实现较为灵活,但缺点便是依赖接口实现;
  3. CGLIB实现代理:使用CGLIB框架对不实现接口的类实现动态代理,其原理便是另外创建一个子类,这个子类继承了被代理类,同时通过字节码编程将额外加入的功能动态编译进新建的代理类中实现动态代理。其本质上是通过字节码框架完成,且因为是继承重写原来的类,因此原来的类和方法不要声明成final,否则会织入失败。

二、AspectJ源码解析

Spring AOP的实现依赖于两个pom包,spring-aop以及aspectjweaver:

  • spring-aop的作用便是集成aop,使spring框架支持aop操作,类似于spring-mvc包使得spring支持web mvc一样;
  • aspectjweaver的作用便是提供实际的aop操作,使用cglib实现类的动态代理。

当然也可以使用spring-aspects包来代替这两个包,因为这个pom中包含了spring-aop和aspectjweaver。

需要注意的是,如果只对AOP的大致流程感兴趣则只需要看AOP结构组成即可,如果有兴趣了解AOP源码分析流程及Springboot对AOP的自动配置集成可以看后续部分。

1.代码示例

代码示例以传统的SpringMVC模式来做demo:

1.1 aspect类:

@Component
@Aspect
public class AspectjController {
    @Pointcut("execution(* com.iboxpay.controller.*.*(..))")
    public void aspectjController() {
    }
    @Before("aspectjController()")
    public void before(JoinPoint joinPoint) {
        String name = joinPoint.getSignature().getName();
        Object[] objs = joinPoint.getArgs();
        System.out.println("before entry");
    }
    @After("aspectjController()")
    public void after() {
        System.out.println("after entry");
    }
}

1.2 Maven:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>
或者
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.9</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>

1.3 applicatioin.xml

<!-- 添加如下配置以支持aspectj -->
<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"/>

2.AOP结构组成

AOP结构流程图如下:

整体流程如下:

  1. Spring工厂调用getBean方法初始化Bean,进入到BeanPostProcessor实现类中;
  2. 在XXXXAutoProxyCreator类中从Spring工厂和Advisor工厂中获取Advisor;
  3. 使用Advisor对象中内嵌的advisorFactory对象工厂获取具体的Advice,同时将Pointcut对象也当成参数传进去,从而获取Advice以及绑定其关系。

AOP结构类图如下:

上面是一张AOP结构组成简易类图,可大致分为五部分:

  1. @Pointcut注解以及实现子类部分:这部分的主要功能便是确定切入点,并且对@Pointcut中的值进行解析,在程序中Pointcut类将会和Advice部分绑定;
  2. @Around等注解对应类:这部分包括Advice、afterAdvice和BeforeAdvice等接口,这些接口的实现类则是对应注解处理的地方。同时这部分是我们开发者直接使用接触的,先使用@Pointcut来确定切入点,而@Around、@Before和@After等注解的方法则是用来实现我们切入逻辑的地方;
  3. Advisor以及实现子类部分:这部分功能主要是将Advice和Pointcut这两个部分融合搭配使用,在程序中表现为传入Pointcut实例化Advice;
  4. Advice工厂部分:在图中表现为ApsectJAdvisorFactory,顾名思义,这是一个产生Advisor的工厂类,但不同的是这个实现类中也会根据注解类型实例化不同的Advice;
  5. 和Spring工厂刷新流程对接部分:即图中最左侧的部分,包括BeanPostProcessor和Proxy-Config的一系列实现类。这部分的主要功能便是将AOP的创建过程嵌入到Spring框架流程,同时通过@AspectJ注解来确定哪些类需要被代理,进而完成一系列操作。

3.源码分析

本篇以最常见也是最常使用的AOP方式来做示例源码分析,说明一下在这种配置下spring内部是如何对一个Bean进行动态代理的。

3.1 AnnotationAwareAspectJAutoProxyCreator类注入流程

说到aspectj的AOP实现方式就绕不开这个类:实现SmartInstantiationAwareBeanPostProcessor接口,而该接口而实现了InstantiationAwareBeanPostProcessor接口,这里是重要的一环,这个接口的postProcessBeforeInstantiation方法和postProcessAfterInitialization方法的调用地方等下会在spring的onfresh流程中说到。

那么这个类是怎么被注册进spring工厂中的呢?在xml中配置了<aop:aspectj-autoproxy/>标签,这个标签的处理类是AopNamespaceHandler命名空间处理类处理的,其源码如下:

public class AopNamespaceHandler extends NamespaceHandlerSupport {
   @Override
   public void init() {
      registerBeanDefinitionParser("config", 
              new ConfigBeanDefinitionParser());
      registerBeanDefinitionParser("aspectj-autoproxy", 
              new AspectJAutoProxyBeanDefinitionParser());
      registerBeanDefinitionDecorator("scoped-proxy", 
              new ScopedProxyBeanDefinitionDecorator());
      registerBeanDefinitionParser("spring-configured", 
              new SpringConfiguredBeanDefinitionParser());
   }
}

可以看到很简洁,现在看到处理aspectj-autoproxy标签AspectJAutoProxyBeanDefinitionParser类,该方法中的调用链又调用了AopNamespaceUtils和AopConfigUtils类,接下来我们一起看看这三个类关键的源码:

class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
   @Override
   public BeanDefinition parse(Element element, 
           ParserContext parserContext) {
      AopNamespaceUtils
                  .registerAspectJAnnotationAutoProxyCreatorIfNecessary(
                          parserContext, element);
      extendBeanDefinition(element, parserContext);
      return null;
   }
}
public abstract class AopNamespaceUtils {
    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 abstract class AopConfigUtils {
    public static BeanDefinition 
            registerAspectJAnnotationAutoProxyCreatorIfNecessary(
                    BeanDefinitionRegistry registry, Object source) {
       return registerOrEscalateApcAsRequired(
               AnnotationAwareAspectJAutoProxyCreator.class, registry, 
                       source);
    }
}

可以看到在AspectJAutoProxyBeanDefinitionParser类中先调用了parse方法,之后又调用了AopNamespaceUtils类的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法,在该方法中接着又调用了AopConfigUtils类的registerAspectJAnnotationAutoProxyCreatorIfNecessary静态方法,在这个静态方法里面调用了registerOrEscalateApcAsRequired方法,参数分别为registry注册工厂以及AnnotationAwareAspectJAutoProxyCreator类,至此,这个关键的类便被注册进spring工厂中。

3.2 spring刷新上下文的调用入口

其源码如下:

public abstract class AbstractApplicationContext 
        extends DefaultResourceLoader
        implements ConfigurableApplicationContext, DisposableBean {
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        ...
        finishBeanFactoryInitialization(beanFactory);
        ...
    }
    protected void finishBeanFactoryInitialization(
            ConfigurableListableBeanFactory beanFactory) {
       if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
             beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, 
                     ConversionService.class)) {
          beanFactory.setConversionService(beanFactory
                  .getBean(CONVERSION_SERVICE_BEAN_NAME, 
                          ConversionService.class));
       }
       if (!beanFactory.hasEmbeddedValueResolver()) {
          beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
             @Override
             public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
             }
          });
       }
       String[] weaverAwareNames = beanFactory
               .getBeanNamesForType(LoadTimeWeaverAware.class, 
                       false, false);
       for (String weaverAwareName : weaverAwareNames) {
          getBean(weaverAwareName);
       }
       beanFactory.setTempClassLoader(null);
       beanFactory.freezeConfiguration();
       beanFactory.preInstantiateSingletons();
    }
}

在spring刷新过程中初始化aspectj的方法流程调用链如下:

  1. refresh();
  2. finishBeanFactoryInitialization();
  3. beanFactory.preInstantiateSingletons()。

3.3 DefaultListableBeanFactory类

其关键源码如下:

public class DefaultListableBeanFactory 
        extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry,
        Serializable {
    @Override
    public void preInstantiateSingletons() throws BeansException {
       ...
       for (String beanName : beanNames) {
          RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
          if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
             if (isFactoryBean(beanName)) {
                ...
             }
             else {
                getBean(beanName);
             }
          }
       }
       ...
    }
    @Override
    public Object getBean(String name) throws BeansException {
       return doGetBean(name, null, null, false);
    }
    protected <T> T doGetBean(
      final String name, final Class<T> requiredType, final Object[] args, 
              boolean typeCheckOnly)
      throws BeansException {

       if (sharedInstance != null && args == null) {
          ...
       }
       else {
          try {
             ...
             if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, 
                        new ObjectFactory<Object>() {
                   @Override
                   public Object getObject() throws BeansException {
                      try {
                         return createBean(beanName, mbd, args);
                      }
                      catch (BeansException ex) {
                         destroySingleton(beanName);
                         throw ex;
                      }
                   }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, 
                        beanName, mbd);
             }
             ...
          catch (BeansException ex) {
             cleanupAfterBeanCreationFailure(beanName);
             throw ex;
          }
       }
       ...
       return (T) bean;
    }
    public Object getSingleton(String beanName, 
            ObjectFactory<?> singletonFactory) {
       synchronized (this.singletonObjects) {
          Object singletonObject = this.singletonObjects.get(beanName);
          if (singletonObject == null) {
             ...
             try {
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
             }
             ...
             finally {
                if (recordSuppressedExceptions) {
                   this.suppressedExceptions = null;
                }
                afterSingletonCreation(beanName);
             }
             if (newSingleton) {
                addSingleton(beanName, singletonObject);
             }
          }
          return (singletonObject != NULL_OBJECT ? singletonObject : null);
       }
    }
    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, 
            Object[] args) throws BeanCreationException {
       ...
       try {
           Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
           if (bean != null) {
              return bean;
           }
        }
       ...
       Object beanInstance = doCreateBean(beanName, mbdToUse, args);
       ...
       return beanInstance;
    }
    protected Object doCreateBean(final String beanName, 
            final RootBeanDefinition mbd, final Object[] args)
      throws BeanCreationException {
       ...
       try {
          populateBean(beanName, mbd, instanceWrapper);
          if (exposedObject != null) {
             exposedObject = initializeBean(beanName, exposedObject, mbd);
          }
       }
       catch (Throwable ex) {
          ...
       }
       ...
       return exposedObject;
    }
    protected Object initializeBean(final String beanName, 
            final Object bean, RootBeanDefinition mbd) {
       ...
       Object wrappedBean = bean;
       if (mbd == null || !mbd.isSynthetic()) {
          wrappedBean = applyBeanPostProcessorsBeforeInitialization(
                  wrappedBean, beanName);
       }
       try {
           invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
           throw new BeanCreationException(
                 (mbd != null ? mbd.getResourceDescription() : null),
                 beanName, "Invocation of init method failed", ex);
        }
       if (mbd == null || !mbd.isSynthetic()) {
          wrappedBean = applyBeanPostProcessorsAfterInitialization(
                  wrappedBean, beanName);
       }
       return wrappedBean;
    }
    @Override
    public Object applyBeanPostProcessorsBeforeInitialization(
            Object existingBean, String beanName)
            throws BeansException {
       Object result = existingBean;
       for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
          result = beanProcessor.postProcessBeforeInitialization(result, 
                  beanName);
          if (result == null) {
             return result;
          }
       }
       return result;
    }
    @Override
    public Object applyBeanPostProcessorsAfterInitialization(
            Object existingBean, String beanName)
            throws BeansException {
       Object result = existingBean;
       for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
          result = beanProcessor.postProcessAfterInitialization(result, 
                  beanName);
          if (result == null) {
             return result;
          }
       }
       return result;
    }
}

由于beanFactory的preInstantiateSingletons方法流程过于复杂,因此只去了调用方法链相关的代码,其它的便使用“...”代替,否则过于占篇幅。其方法调用链如下:

  1. preInstantiateSingletons方法;
  2. getBean方法;
  3. 调用doGetBean方法;
  4. 调用进getSingleton方法,并且传入的对象是beanName和ObjectFactory对象,该对象的getObject方法是直接调用createBean方法;
  5. 调用singletonFactory方法的getObject方法;
  6. createBean方法;
  7. 调用resolveBeforeInstantiation方法,该方法的调用链会调用postProcessBeforeInstantiation方法;
  8. doCreateBean方法;
  9. initializeBean方法;
  10. 调用applyBeanPostProcessorsBeforeInitialization方法,该方法中会调用postProcessBeforeInitialization方法;
  11. 调用invokeInitMethods方法,该方法中调用了熟悉的方法afterPropertiesSet;
  12. 调用applyBeanPostProcessorsAfterInitialization方法,该方法中会调用postProcessAfterInitialization方法。

3.4 AbstractAutoProxyCreator类

该类是AnnotationAwareAspectJAutoProxyCreator类的抽象父类,其源码如下:

public abstract class AbstractAutoProxyCreator 
        extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, 
        BeanFactoryAware {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, 
            String beanName) throws BeansException {
       Object cacheKey = getCacheKey(beanClass, beanName);
       if (beanName == null || 
               !this.targetSourcedBeans.contains(beanName)) {
          if (this.advisedBeans.containsKey(cacheKey)) {
             return null;
          }
          // 判断是否被@AspectJ注解注释
          if (isInfrastructureClass(beanClass) || 
                  shouldSkip(beanClass, beanName)) {
             this.advisedBeans.put(cacheKey, Boolean.FALSE);
             return null;
          }
       }
       if (beanName != null) {
          TargetSource targetSource = getCustomTargetSource(beanClass, 
                  beanName);
          if (targetSource != null) {
             this.targetSourcedBeans.add(beanName);
             // 将调用这个方法从Spring工厂中获得已经注册进去的Advisor,或者使用
             // Advisor工厂获得Advisor对象
             Object[] specificInterceptors = 
                     getAdvicesAndAdvisorsForBean(beanClass, beanName, 
                             targetSource);
             // 创建代理对象
             Object proxy = createProxy(beanClass, beanName, 
                     specificInterceptors, targetSource);
             this.proxyTypes.put(cacheKey, proxy.getClass());
             return proxy;
          }
       }
       return null;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, 
            String beanName) throws BeansException {
       if (bean != null) {
          Object cacheKey = getCacheKey(bean.getClass(), beanName);
          if (!this.earlyProxyReferences.contains(cacheKey)) {
             return wrapIfNecessary(bean, beanName, cacheKey);
          }
       }
       return bean;
    }
    protected Object wrapIfNecessary(Object bean, String beanName, 
            Object cacheKey) {
       if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
          return bean;
       }
       if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
          return bean;
       }
       // 判断是否被@AspectJ注解注释
       if (isInfrastructureClass(bean.getClass()) || 
               shouldSkip(bean.getClass(), beanName)) {
          this.advisedBeans.put(cacheKey, Boolean.FALSE);
          return bean;
       }
       // 将调用这个方法从Spring工厂中获得已经注册进去的Advisor,或者使用
       // Advisor工厂获得Advisor对象
       Object[] specificInterceptors = 
               getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
       if (specificInterceptors != DO_NOT_PROXY) {
          this.advisedBeans.put(cacheKey, Boolean.TRUE);
          Object proxy = createProxy(
                bean.getClass(), beanName, specificInterceptors, 
                new SingletonTargetSource(bean));
          this.proxyTypes.put(cacheKey, proxy.getClass());
          return proxy;
       }
       this.advisedBeans.put(cacheKey, Boolean.FALSE);
       return bean;
    }
    protected Object createProxy(
      Class<?> beanClass, String beanName, Object[] specificInterceptors, 
      TargetSource targetSource) {
       if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
          AutoProxyUtils.exposeTargetClass(
                  (ConfigurableListableBeanFactory) this.beanFactory, 
                  beanName, beanClass);
       }
       // 获得生成代理对象的工厂,这里面将会具体实例化cglib或者JDK动态代理对象
       ProxyFactory proxyFactory = new ProxyFactory();
       proxyFactory.copyFrom(this);
       if (!proxyFactory.isProxyTargetClass()) {
          if (shouldProxyTargetClass(beanClass, beanName)) {
             proxyFactory.setProxyTargetClass(true);
          }
          else {
             evaluateProxyInterfaces(beanClass, proxyFactory);
          }
       }
       // 创建具体的Advisor,实际上如果是AspectJ处理的Advisor类型
       // 都是specificInterceptors数组的值
       // 其中有一个类型是InstantiationModelAwarePointcutAdvisorImpl
       Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
       for (Advisor advisor : advisors) {
          proxyFactory.addAdvisor(advisor);
       }
       proxyFactory.setTargetSource(targetSource);
       customizeProxyFactory(proxyFactory);
       proxyFactory.setFrozen(this.freezeProxy);
       if (advisorsPreFiltered()) {
          proxyFactory.setPreFiltered(true);
       }
       // 从获得的代理工厂对象中获得代理类
       return proxyFactory.getProxy(getProxyClassLoader());
    }
}

终于到了最终处理@Aspect注解和该注解搭配使用的@Before、@PointCut等注解类了,在该类中有两个方法是非重要:postProcessBeforeInstantiation和postProcessAfterInitialization。

postProcessBeforeInstantiation方法,该方法作用有两个,一是提前判断@Aspect等注解,然后将其放进advisedBeans对象中,提供给后续的流程使用;二是使用自定义创建代理类的bean来创建代理类,实现个性化的要求。对于我们平时使用的@Aspect注解和@Controller这种的搭配使用,一般用到的作用就第一个。

接下来说下重点方法postProcessAfterInitialization,该方法流程大致如下:

  1. 进入方法后调用getCacheKey方法,获得根据spring的特殊规则(如果是FactoryBean则加上“&”的前缀)返回beanName;
  2. 如果是第一次进入该方法的beanName则调用wrapIfNecessary方法,否则直接返回;
  3. 判断targetSourcedBeans自定义bean、advisedBeans以及@Aspect注解这三个是否符合条件,符合条件直接返回,不符合条件的将会继续往下走,第一次进来的@Controller注解类会继续往下走;
  4. 调用子类AbstractAdvisorAutoProxyCreator的getAdvicesAndAdvisorsForBean方法来获得specificInterceptors对象:
    1. 调用findEligibleAdvisors方法;
    2. 调用findCandidateAdvisors方法,该方法会返回所有被@Aspect注解的类中再被@Before等注解过的类和方法;
    3. 使用刚刚返回的结果调用findAdvisorsThatCanApply方法,判断哪些切面方法可以被使用在该beanName上,在当前情况下方法里面具体是根据PointCut判断的;
    4. 调用extendAdvisors方法,添加ExposeInvocationInterceptor.ADVISOR对象;
    5. 如果获得的eligibleAdvisors对象不为空则对其进行排序,后续直接返回。
  5. 如果返回的specificInterceptors对象不等于DO_NOT_PROXY,则使用cglib对该对象进行动态代理:
    1. 将当前处理的beanName(即cacheKey)添加进advisedBeans集合,并且值为true,在该集合中如果是被AOP的类则是true,不是的话则是false;
    2. 调用createProxy方法,使用cglib将对象bean和specificInterceptors创建代理对象;
    3. 创建成功后将结果放进proxyTypes集合中后续返回代理对象。

至此,在调用applyBeanPostProcessorsAfterInitialization方法后,便可以获得被cglib代理的对象了。该对象中的方法将会被@Aspect类中的方法加强,以达到性能检测、日志打印或者其它功能的作用。

4.springboot对AOP的自动集成

在我们熟悉的spring-autoconfigure包中的路径/META-INF/spring.factories文件里配置了AOP的自动集成类,配置如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration

4.1 AopAutoConfiguration类

AopAutoConfiguration自动配置类就这样展示在我们面前,它的源码如下:

@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, 
        Advice.class, AnnotatedElement.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", 
        havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
   @Configuration
   @EnableAspectJAutoProxy(proxyTargetClass = false)
   @ConditionalOnProperty(prefix = "spring.aop", 
           name = "proxy-target-class", havingValue = "false",
           matchIfMissing = false)
   public static class JdkDynamicAutoProxyConfiguration {

   }
   @Configuration
   @EnableAspectJAutoProxy(proxyTargetClass = true)
   @ConditionalOnProperty(prefix = "spring.aop", 
           name = "proxy-target-class", havingValue = "true",
           matchIfMissing = true)
   public static class CglibAutoProxyConfiguration {

   }
}

在其中我们看到了“proxy-target-class”属性,是不是觉得很熟悉?没错,这个就是SpringMVC中的配置标签<aop:aspectj-autoproxy/>的属性,被springboot写在了AopAutoConfiguration类中,在其中的类CglibAutoProxyConfiguration上的注解属性为true,表明spring的aop将会使用CglibAutoProxyConfiguration类使用。

4.2 EnableAspectJAutoProxy注解

注解的源码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
   boolean proxyTargetClass() default false;
   boolean exposeProxy() default false;
}

可以看到该注解被@Import注解了,并且其中的值为AspectJAutoProxyRegistrar类,因此我们接下来看到该类的源码。

4.3 AspectJAutoProxyRegistrar类

该类的源码如下:

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
   @Override
   public void registerBeanDefinitions(
         AnnotationMetadata importingClassMetadata, 
         BeanDefinitionRegistry registry) {
      AopConfigUtils
          .registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
      AnnotationAttributes enableAspectJAutoProxy =
            AnnotationConfigUtils.attributesFor(importingClassMetadata, 
            EnableAspectJAutoProxy.class);
      if (enableAspectJAutoProxy != null) {
         if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
            AopConfigUtils.
                    forceAutoProxyCreatorToUseClassProxying(registry);
         }
         if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
            AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
         }
      }
   }
}

是不是又看到了熟悉的朋友呢,就是在AopConfigUtils类中的调用方法链会注册Aspect关键类的方法registerAspectJAnnotationAutoProxyCreatorIfNecessary,在这个方法的调用链将会把AnnotationAwareAspectJAutoProxyCreator注册进bean工厂中。从而达到SpringMVC在xml文件中配置<aop:aspectj-autoproxy/>标签的同样效果。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值