Spring:AOP 是如何与 IoC 整合的?

72 阅读2分钟

Spring Bean 生命周期

简单回顾一下 Spring Bean 与 AOP 相关的生命周期:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 
        throws BeanCreationException { 
    // 实例化 
    instanceWrapper = createBeanInstance(beanName, mbd, args); 
    // 针对循环依赖问题暴露单例工厂类,向 singletonFactories 放入 Lambda 表达式
    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 
    // 属性赋值 
    populateBean(beanName, mbd, instanceWrapper); 
    // 初始化
    exposedObject = initializeBean(beanName, exposedObject, mbd); 
}

在初始化阶段中:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { 
    invokeAwareMethods(beanName, bean); 
    
    // 执行 BeanPostProcessor#postProcessBeforeInitialization 
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); 
    
    invokeInitMethods(beanName, wrappedBean, mbd); 
    
    // 执行 BeanPostProcessor#postProcessAfterInitialization 
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 
    
    return wrappedBean; 
}

AOP 与 IoC 整合

整合的关键是 AbstractAutoProxyCreator,通过类图,直观的看到,AbstractAutoProxyCreator 就是一个 BeanPostProcessor,作用于 Spring Bean 生命周期的初始化阶段中。

image.png

在创建 Proxy 的 AbstractAutoProxyCreator 中,关注以下方法:

  • getEarlyBeanReference
  • postProcessAfterInitialization
  • wrapIfNecessary

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport 
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { 

    @Override 
    public Object getEarlyBeanReference(Object bean, String beanName) { 
        Object cacheKey = getCacheKey(bean.getClass(), beanName); 
        this.earlyProxyReferences.put(cacheKey, bean); 
        // (1) 
        return wrapIfNecessary(bean, beanName, cacheKey); 
    } 
    
    @Override 
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { 
        // Create proxy here if we have a custom TargetSource. 
        // Suppresses unnecessary default instantiation of the target bean: 
        // The TargetSource will handle target instances in a custom fashion. 
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName); 
        if (targetSource != null) { 
            if (StringUtils.hasLength(beanName)) { 
                this.targetSourcedBeans.add(beanName); 
            } 
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); 
            // 当存在用户自定义的 targetSource 时
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); 
            this.proxyTypes.put(cacheKey, proxy.getClass()); 
            return proxy; 
        } 
        return null; 
    } 

    @Override 
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { 
        if (bean != null) { 
            Object cacheKey = getCacheKey(bean.getClass(), beanName); 
            if (this.earlyProxyReferences.remove(cacheKey) != bean) { 
                // (2) 
                return wrapIfNecessary(bean, beanName, cacheKey); 
            } 
        } 
        return bean; 
    } 

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { 
        // 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; 
    } 
}

可以看到,在 wrapIfNecessary 中调用 createProxy 创建代理,而 wrapIfNecessary 有两个地方进行使用:

  1. postProcessAfterInitialization 中,是在 Bean 初始化过程中创建代理对象;
  2. getEarlyBeanReference 中,用于提前暴露代理对象(将 ObjectFactory 存放到三级缓存(singletonFactories)中),作用于存在循环依赖的 Bean 初始化过程中,对应位置在:doCreateBean() 的 addSingletonFactory 中。

另外,在 postProcessBeforeInstantiation (实例化阶段)中也使用了 createProxy 创建了代理对象,这是在用户使用自定义的 targetSource 时创建代理的方式,会直接跳过 doCreateBean(这种情况比较少见),如下:

image.png