Spring中AOP的高级分析EnableAspectjAutoProxy注解是如何执行的

2021-02-23 11:17发布

3条回答
studentaaa
2021-02-24 10:10

spring使用aspectj提供的库进行切入点解析和匹配,解释与aspectj 5相同的注释。但是,AOP运行时仍然是纯SpringAOP,并且不依赖于AspectJ编译器或weaver。

springAOP不管是用jdk动态代理还是cglib动态代理,跟aspectj的最大区别是SpringAOp用的是动态代理运行期织入,而aspectj是使用的静态代理在编译期织入。

先看@EnableAspectJAutoProxy注解,通过Import引入AspectJAutoProxyRegistrar,AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口。ImportBeanDefinitionRegistrar接口的作用就是把BeanDefinitionRegistry传递给我们,我们可以通过这个注册器完成beanDefinition的注册。

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

接着再看AspectJAutoProxyRegistrar都做了些什么

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {  @Override public void registerBeanDefinitions(   AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {  //注册AnnotationAwareAspectJAutoProxyCreator  AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);  AnnotationAttributes enableAspectJAutoProxy =    AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);  //判断配置类AppConfig是否加了@EnableAspectJAutoProxy注解  if (enableAspectJAutoProxy != null) {   //默认是false指用jdk动态代理,值为true则开启cglib代理   if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);   }   if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {    AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);   }  } }}

首先注册了一个AnnotationAwareAspectJAutoProxyCreator,先看这个类的继承结构图

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {  return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null); }
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(   BeanDefinitionRegistry registry, @Nullable Object source) {  return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
private static BeanDefinition registerOrEscalateApcAsRequired(   Class cls, BeanDefinitionRegistry registry, @Nullable 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; }

一周热门 更多>