SpringAop源码(二)- EnableAspectJAutoProxy实现原理(上)

目录

一、AspectJAutoProxyRegistrar

二、AnnotationAwareAspectJAutoProxyCreator

1、ProxyConfig

2、ProxyProcessorSupport

3、AbstractAutoProxyCreator

4、AbstractAdvisorAutoProxyCreator

5、AspectJAwareAdvisorAutoProxyCreator

6、AnnotationAwareAspectJAutoProxyCreator

三、BeanFactoryAware的setBeanFactory

四、BeanPostProcessor的postProcessAfterInitialization

1、getAdvicesAndAdvisorsForBean(获取切面)

2、createProxy(创建代理)


一、AspectJAutoProxyRegistrar

    @EnableAspectJAutoProxy方式开启Spring Aop注解,其两个注解的属性和Spring的自动代理在上一篇已经分析过了。那看看添加注解后做了什么。 

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {    }

将 AspectJAutoProxyRegistrar注入为Bean,结构如下:

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

    实现了 ImportBeanDefinitionRegistrar接口的 registerBeanDefinitions方法,将注入BeanDefinition,如果我们设置EnableAspectJAutoProxy的两个属性,那么也将其注入BeanDefinition中。所以关键在AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

public static BeanDefinition 
    registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
    BeanDefinitionRegistry registry, @Nullable Object source) {

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

最后发现是将AnnotationAwareAspectJAutoProxyCreator的RootBeanDefinition注入容器中,AbstractApplicationContext的refresh的最后阶段循环调用getBean() 将所有的bean初始化。

二、AnnotationAwareAspectJAutoProxyCreator

看看结构:

从顶层开始分析其父类都有什么:

1、ProxyConfig

ProxyConfig中定义了很多获取代理的时候的属性,详细可以参见: SpringAop源码-基本概念和自动代理的Spring Aop的自动代理

public class ProxyConfig implements Serializable {
    
    private boolean proxyTargetClass = false;

    private boolean optimize = false;

    boolean opaque = false;

    boolean exposeProxy = false;

    private boolean frozen = false;
}

2、ProxyProcessorSupport

    主要是定义了排序,类加载器。实现了BeanClassLoaderAware接口,在回调中设置类加载器。

public class ProxyProcessorSupport extends ProxyConfig implements Ordered, 
    BeanClassLoaderAware, AopInfrastructureBean {

    private int order = Ordered.LOWEST_PRECEDENCE;

    @Nullable
    private ClassLoader proxyClassLoader = ClassUtils.getDefaultClassLoader();

    private boolean classLoaderConfigured = false;
}

3、AbstractAutoProxyCreator

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    
    @Nullable
    protected static final Object[] DO_NOT_PROXY = null;

    protected static final Object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS = new Object[0];

    private AdvisorAdapterRegistry advisorAdapterRegistry = 
        GlobalAdvisorAdapterRegistry.getInstance();

    private boolean freezeProxy = false;

    private String[] interceptorNames = new String[0];

    private boolean applyCommonInterceptorsFirst = true;

    @Nullable
    private TargetSourceCreator[] customTargetSourceCreators;

    @Nullable
    private BeanFactory beanFactory;

    private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);

    private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);

    private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);
}
  • Object[] DO_NOT_PROXY:不使用代理的对象
  • boolean freezeProxy:是否自定义代理(不使用Spring自动代理方式)
  • AdvisorAdapterRegistry:
  • TargetSourceCreator customTargetSourceCreators:自定义的目标对象创建器,就一个接口可以获取目标对象
  • BeanFactory beanFactory:实现了BeanFactoryAware,会在回调方法setBeanFactory中进行赋值
  • Set<String> targetSourcedBeans:存储Spring Bean类型的代理对象 的Bean名称
  • ConcurrentHashMap earlyProxyReferences:用于存储Bean是否有被Aop代理过,就是缓存机制
  • ConcurrentHashMap proxyTypes:存储创建过代理的代理类,key为Bean的名称(处理过&的)
  •  
  • ConcurrentHashMap advisedBeans:缓存Bean是否创建代理

 

4、AbstractAdvisorAutoProxyCreator

只有一个属性,但是实现了父类的setBeanFactory,后面分析。

private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;

5、AspectJAwareAdvisorAutoProxyCreator

实现了父类的 sortAdvisors、extendAdvisors、shouldSkip重要方法,后面分析。

6、AnnotationAwareAspectJAutoProxyCreator

两个重要的字段在setBeanFactory方法中初始化,后面分析。

@Nullable
private AspectJAdvisorFactory aspectJAdvisorFactory;

@Nullable
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;

并且实现了很多接口,做了很多重要的事情:

  • 1、实现了BeanClassLoaderAware将类加载器回调注入,后续使用

  • 2、实现了BeanFactoryAware将BeanFactory回调注入,并且调用了父类AbstractAdvisorAutoProxyCreator定义的接口 initBeanFactory,并且AnnotationAwareAspectJAutoProxyCreator重新了该接口
  • 3、实现了BeanPostProcessor的postProcessAfterInitialization接口,在声明周期中会回调,详细见:Spring-Bean的作用域和生命周期
  • 4、实现了SmartInstantiationAwareBeanPostProcessor的predictBeanTypegetEarlyBeanReference接口。

 

三、BeanFactoryAware的setBeanFactory

@Override
public void setBeanFactory(BeanFactory beanFactory) {
    super.setBeanFactory(beanFactory);
    if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
        throw new IllegalArgumentException(
        "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
    }
    initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}

在父类AbstractAdvisorAutoProxyCreator中,实现了setBeanFactory接口

1、将BeanFactory进行保存,后续进行使用

2、调用了一个自己定义的子类可以重写的initBeanFactory接口,并且AnnotationAwareAspectJAutoProxyCreator也重写了该接口,具体initBeanFactory中初始化了两个内部变量,如下:

protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    super.initBeanFactory(beanFactory);
    if (this.aspectJAdvisorFactory == null) {
        this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
    }
    this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(
        beanFactory, this.aspectJAdvisorFactory);
}

四、BeanPostProcessor的postProcessAfterInitialization

    继承自BeanPostProcessor,那么在AbstractApplicationContext的refresh的最后阶段,会将所有单利的非懒加载的Bean进行getBean()初始化,每个Bean初始化都会调用当前重写了BeanPostProcessor的postProcessBeforeInitialization(该方法没有做什么直接返回了原Bean信息),而在postProcessAfterInitialization中进行了处理,如下:

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}
protected Object getCacheKey(Class<?> beanClass, @Nullable String beanName) {
    if (StringUtils.hasLength(beanName)) {
        return (FactoryBean.class.isAssignableFrom(beanClass) ?
            BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
    } else {
        return beanClass;
    }
}

先获取一个缓存该Bean的key,如果是FactoryBean的子类那么在前面加上BeanFactory.FACTORY_BEAN_PREFIX那么后面从工厂中拿到的就是原对象,否则直接返回Bean的名称。重要的是如果在自己内部有一个缓存,如果没有缓存过,则执行wrapIfNecessary方法,如下:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // Create proxy if we have advice.
    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;
}
  • 1、目标对象(TargetSource)集合是否存储过
  • 2、advisedBeans设置为不进行代理
  • 3、判断是否为Spring Aop几个定义类的子类,或者其他Spring组件,则直接加入advisedBeans中(前基本都是用缓存加快处理速度)
  • 4、获取切面getAdvicesAndAdvisorsForBean
  • 5、创建代理进行返回:createProxy();
  • 6 、添加到其他缓存中,加快判断

 

其中主要逻辑是:获取切面(Spring Bean切面 和 @AspectJ切面) 和  创建代理,分为后续分析:

 getAdvicesAndAdvisorsForBean:SpringAop源码-EnableAspectJAutoProxy实现原理(中)- getAdvicesAndAdvisorsForBean

createProxy():SpringAop源码-EnableAspectJAutoProxy实现原理(下)- createProxy

           

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值