spring aop切面实现对bean增强的过程

49 篇文章 1 订阅

spring的两大核心就是ioc和aop。在关于ioc依赖注入的文章中,我们了解了如何根据BeanDefinition创建Bean,然后在BeanPostProcessor中处理@Autowired和@Resource两个注解,自动注入Bean。

本文将讲解另外一块核心内容,aop切面。

AOP自动配置

首先,aop切面基于springboot的自动配置。如果不了解自动配置,请参考自动配置机制的文章。

为此,我们先找到aop自动配置的类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 {

    }

}

 我们将以Cglib为主要的了解对象,可以看到CglibAutoProxyConfiguration上注解了一个@EnableAspectJAutoProxy,它意味着开启切面代理,我们打开该注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

    //
}

我们看到,@Import注解导入了AspectJAutoProxyRegistrar。在自动配置的文章中,我们了解到ConfigurationClassParser将会处理@Import注解。这里我们不再关注如何处理@Import注解,直接打开AspectJAutoProxyRegistrar类看看

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 注册自动切面代理的创建器
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

        // 省略
    }

}

跟进registerAspectJAnnotationAutoProxyCreatorIfNecessary

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}

继续跟进registerAspectJAnnotationAutoProxyCreatorIfNecessary

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
        BeanDefinitionRegistry registry, @Nullable Object source) {

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

我们看到,调用registerOrEscalateApcAsRequired方法指定了一个类AnnotationAwareAspectJAutoProxyCreator,这个类将作为创建代理的类

跟进registerOrEscalateApcAsRequired方法

private static BeanDefinition registerOrEscalateApcAsRequired(
        Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

    //
    // 构建BeanDefinition
    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    // 注册到Bean容器
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
}

可以看到,最终是注册到了Bean容器中,作为BeanDefinition存在。我们可以认为aop的自动配置过程就是为了创建AnnotationAwareAspectJAutoProxyCreator这个类的BeanDefinition。

注册AnnotationAwareAspectJAutoProxyCreator

首先,我们先看看AnnotationAwareAspectJAutoProxyCreator的继承结构

可以看到,AnnotationAwareAspectJAutoProxyCreator最终是实现了BeanPostProcessor,那BeanPostProcessor是什么时候被创建为Bean的呢?

这里,我们得回到refresh容器过程的refresh方法中,跟进AbstractApplicationContext的refresh方法

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 

        try {
            // 

            // 注册BeanDefinition到容器
            invokeBeanFactoryPostProcessors(beanFactory);

            // 注册后置处理器到容器
            registerBeanPostProcessors(beanFactory);

            //
        }
        //
    }
}

在注册BeanDefinition之后,就会把BeanPostProcessor的BeanDefinition转化为了Bean注册到容器中。registerBeanPostProcessors结束以后,AnnotationAwareAspectJAutoProxyCreator就以Bean的形式存在于BeanFactory中了。

触发AnnotationAwareAspectJAutoProxyCreator

接着,我们再看AnnotationAwareAspectJAutoProxyCreator被注册为Bean以后,是在什么位置被触发的。前面,ioc依赖注入的文章中我们提到过createBean方法,将会根据BeanDefinition创建Bean。

跟进AbstractAutowireCapableBeanFactory的createBean方法

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    //

    try {
        // BeanPostProcessors 调用
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    //

    try {
        // 创建实例对象
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        //
        return beanInstance;
    }
    //
}

我们看到,在doCreateBean之前,先触发resolveBeforInstantiation方法,调用了AnnotationAwareAspectJAutoProxyCreator。

切面解析

跟进resolveBeforeInstantiation

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            //
            if (targetType != null) {
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                //
            }
        }
        //
    }
    return bean;
}

继续跟进applyBeanPostProcessorBeforeInstantiation方法

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            // 触发postProcesBeforeInstantiation
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

继续跟进AbstractAutoProxyCreator的postProcessBeforeInstantiation方法

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    Object cacheKey = getCacheKey(beanClass, beanName);

    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
        //
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

    //
    return null;
}

isInfrastructureCLass将返回false,跟进AspectJAwareAdvisorAutoProxyCreator的shouldSkip

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
    // 返回所有的通知,如@Before @After @AfterThrowing @Round
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    for (Advisor advisor : candidateAdvisors) {
        if (advisor instanceof AspectJPointcutAdvisor &&
                ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
            return true;
        }
    }
    return super.shouldSkip(beanClass, beanName);
}

这里的findCandidateAdvisors方法,将会从beanFactory中获得注解了@Aspect的类元数据,然后获取其中定义的Advisor。

到这一步,我们就已经获得了完成了切面部分的解析工作。

代理增强

回到AbstractAutowireCapableBeanFactory的createBean方法

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    //

    try {
        // BeanPostProcessors 调用
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    //

    try {
        // 创建实例对象
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        //
        return beanInstance;
    }
    //
}

获取了Advisor,那么再看看Advisor被增强到Bean上的过程,跟进doCreateBean

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
        throws BeanCreationException {
    //

    if (instanceWrapper == null) {
        // 创建实例对象
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    //

    Object exposedObject = bean;
    try {
        // 自动注入
        populateBean(beanName, mbd, instanceWrapper);
        // 初始化Bean,创建代理的入口
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }

    //
    return exposedObject;
}

我们找到initializeBean,这个初始化Bean的入口,将从这里开始关注代理增强部分,跟进initializeBean方法

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    //
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

继续跟进applyBeanPostProcessorsAfterInitialization方法

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

这里将会调用AbstractAutoProxyCreator的postProcessAfterInitialization方法,跟进方法

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

继续跟进wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    //

    // 获取适用于当前Bean的Advisors
    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;
}

getAdvicesAndAdvisorsForBean方法将会获取到可以增强到该Bean的Advisor,然后createProxy将会创建代理类,并一路返回,如果是单例,则注册到缓存中

跟进createProxy看看创建代理

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
        @Nullable Object[] specificInterceptors, TargetSource targetSource) {

    //

    // 获取可用的advisor
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);

    //
    // 创建并返回代理对象
    return proxyFactory.getProxy(getProxyClassLoader());
}

跟进getProxy

public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
}

createAopProxy将会根据条件返回Cglib实现或者jdk动态代理的实现,然后调用它们的getProxy方法去获取代理对象

总结

本文省略了不少细节内容,大体逻辑是从:aop自动配置 -> 解析@Aspect切面对象 -> 代理增强,这么一个逻辑行文的。

自动配置的核心就是为了导入一个AnnotationAwareAspectJAutoProxyCreator,该类实现了BeanPostProcessor。所以在创建Bean实例对象之前会触发解析@Aspect切面对象,获取Advisor。在生成Bean实例对象之后,会再触发该类对Bean实例对象做代理增强,增强的Advisor来自之前的解析结果。代理增强的实现有cglib和jdk动态代理两种。

最后,增强过的代理Bean如果是单例,将跟以前一样添加到缓存对象中。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值