AOP的原理可以简单这么认为,代理对象持有被代理对象(因为代理对象的字段并不会被赋值,都是null,所以需要用到被代理对象字段的值),通过在调用被代理对象方法前后做一些事情。
在Spring中,我们经常会为我们的Bean做AOP,根据上面我们知道,代理对象需要引用被代理对象,那就需要在Bean初始化完成之后再对Bean做代理。因为Bean初始化完成之后就是一个可用的Bean了,而且会被放入IOC容器,我们需要在这个Bean被放入IOC容器之前生成它的代理对象,并代替原先的类放入IOC容器中。
参考链接:blog.csdn.net/qq_41084438…
这是一个Bean的生命周期流程,当它执行完第六步,也就是初始化方法执行完毕之后,这个Bean就可用了。而第七步是Spring给我们提供的扩展点,在这一步可以拿到可用的原始对象,我们的代理对象生成和替换就是在这里。
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
doGetBean
在循环依赖中我们讲了spring实例化bean的入口,refresh->finishBeanFactoryInitialization->preInstantiateSingletons->getBean->doGetBean,看doGetBean中的如下代码
if (mbd.isSingleton()) {
// 实例化bean
sharedInstance = getSingleton(beanName, () -> {
try {
// 真正的完成bean的创建
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance
(sharedInstance, name, beanName, mbd);
}
createBean
createBean(beanName, mbd, args);方法真正的完成了bean的实例化,包括循环依赖、AOP、生命周期等。
所谓的AOP无非就是将bean加强,在bean的方法前后加上其他的方法而已,bean的class在虚拟机启动的时候就加载到JVM里了,我们不会通过修改class来动态扩展bean的功能,但是可以新生成一个类(动态代理类),这个类呢,包含了bean的所有功能,同时又进行了加强,然后将这个动态代理类实例化,替换掉原有的bean,最后放到spring单例池中。
如果你的类没有被其他类依赖,那么可以在doCreateBean之前就创建好代理对象。
//给Bean后置处理器一个机会,返回一个替代目标对象的代理对象。
//就在这里
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
//注意如果有 InstantiationAwareBeanPostProcessor类型的接口
//并返回了自定义对象 这里会直接返回
return bean;
}
//如果上面直接返回了bean 下面的doCreateBean就不会执行
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
// 给Bean后置处理器一个机会,返回一个替代目标对象的代理对象。
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
//如果尚未被解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//调用InstantiationAwareBeanPostProcessor的
//postProcessBeforeInstantiation
//参数是Class
bean = applyBeanPostProcessorsBeforeInstantiation
(targetType, beanName);
//这里返回的是null
if (bean != null) {
//调用BeanPostProcessor的 postProcessAfterInitialization
//注意是BeanPostProcessor
bean = applyBeanPostProcessorsAfterInitialization
(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
上篇文章提到如果applyBeanPostProcessorsBeforeInstantiation方法返回bean不为空,则实例化结束。不执行下面的doCreateBean方法。
本篇文章和上篇文章相反本篇文章要执行doCreateBean方法。
看下org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
/***
* 创建bean实例 仅仅是创建bean实例
* 1.判断是否存在Supplier和Factory-Method如果有那么就使用并创建实例
* 否则就选择使用构造函数进行构造
* 2.计算构造函数至少有几个参数 选择构造函数
* 3.选择构造函数的参数 下标&通用
* 4.计算构造函数的参数权重
* instanceWrapper实现了 ConfigurablePropertyAccessor
* 是一个包装类 该类的属性可以编辑
* instanceWrapper有一个属性WrappedInstance 里面放的就是我们构造的实例
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
//允许 post-processors 修改 beanDefinition
//这里都已经构造完了实例 在修改beanDefinition 有什么意义呢?
//意义在于虽然构造完了 还没初始化完呀 它的属性这些东西还没设置值
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//调用 MergedBeanDefinitionPostProcessor
//查找出满足条件的属性、方法, 将他们封装起来, 以便后面在填充属性的时候可以直接使用
//https://juejin.cn/post/6844904167945797640
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
/***
* 是否需要提前暴露
* 判断条件:
* 1.是单例
* 2.允许循环依赖
* 3.bean正在被创建
*/
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
//需要提前暴露
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
/***
* singletonObjects 一级缓存池
* earlySingletonObjects 二级缓存池
* singletonFactories 三级缓存池
* 将ObjectFactory<?> singletonFactory 加入三级缓存 singletonFactories
*/
addSingletonFactory(
beanName,
//getEarlyBeanReference放入了提前实例化但是未初始化的对象
//getEarlyBeanReference中获取了所有的SmartInstantiationAwareBeanPostProcessor并调用
//SmartInstantiationAwareBeanPostProcessor中getEarlyBeanReference是一个默认方法
//默认返回的是传入的bean
() -> getEarlyBeanReference(beanName, mbd, bean)
);
}
// Initialize the bean instance.
//这个bean已经放入了 getEarlyBeanReference(beanName, mbd, bean)
Object exposedObject = bean;
try {
/***
* 1.属性填充
* 2.处理属性依赖
* 传入的是 BeanWrapper
*/
populateBean(beanName, mbd, instanceWrapper);
/***
* 初始化bean
* 如果bean实现了以下接口
* BeanNameAware, BeanFactoryAware, ApplicationContextAware
* 则调用对应接口的方法
* 最后bean的代理对象就是在这里被创建的
*/
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException
&& beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
/***
* 是否需要提前暴露 earlySingletonExposure = true
* 判断条件:
* 1.是单例
* 2.允许循环依赖
* 3.bean正在被创建
*/
if (earlySingletonExposure) {
// A 和 B 循环依赖
// 对于A来说
// 如果没有循环依赖不会从三级缓存获取 这里直接返回空
// 如果没有循环依赖 返回空 因为allowEarlyReference是false 所以不会不到三级缓存拿
// 如果有循环依赖 在B填充属性A对象时 会在填充属性的方法中调用 getSingleton(beanName, true);
// 因为allowEarlyReference是true 所以会到三级缓存拿 并放入二级缓存
// 然后在这里获取的就是二级缓存中的对象
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
//判断代理的对象和提前暴露的对象是不是还是一个 注意使用的是 ==
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
//如果不是一个判断是否有依赖该bean的对象
}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
//如果有抛出异常
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
populateBean完成了bean的实例化及循环依赖,继续看initializeBean方法,这个方法就是开启了声明周期,AOP实现也是在这里面。
在docreateBean中执行了exposedObject = initializeBean(beanName, exposedObject, mbd);
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
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;
}
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);这个方法就是完成了AOP代理的实现,他是怎么实现的呢???
在initializeBean方法中有2个重要的方法,分别是执行BeanPostProcessor的前置方法和后置方法。
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
分别对应
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
等等这个applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)方法
不是在上一篇文章就执行过吗?
非也非也。
上一篇文章中执行的是applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
注意看第一个参数,分别是Class 和 Object 。
哦,上一篇文章中对象还没产生,执行的是applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) 所以需要参数需要传1个Class。
这一篇文章bean已经被实例化创建出来了,所以直接传入的是1个被实例化创建出来的bean。
ok,假装很有道理接着往下看
先看AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
getBeanPostProcessors()返回值如下:
result = {CopyOnWriteArrayList@1674} size = 7
0 = {ApplicationContextAwareProcessor@1076}
1 = {ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@1337}
2 = {PostProcessorRegistrationDelegate$BeanPostProcessorChecker@1355}
3 = {AnnotationAwareAspectJAutoProxyCreator@1492} "proxyTargetClass=false; optimize=false; opaque=false; exposeProxy=false; frozen=false"
4 = {CommonAnnotationBeanPostProcessor@1362}
5 = {AutowiredAnnotationBeanPostProcessor@1354}
6 = {ApplicationListenerDetector@1676}
其中有1个AnnotationAwareAspectJAutoProxyCreator,看下postProcessBeforeInitialization的逻辑。
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
原来postProcessBeforeInitialization啥也不做呀。
**注意下面获取的是BeanPostProcessor,还是AnnotationAwareAspectJAutoProxyCreator。**看下AbstractAutoProxyCreator#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;
}
此时AOP创建代理的第二个时机出现了,就在AbstractAutoProxyCreator#postProcessAfterInitialization。
进入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;
}
//isInfrastructureClass(beanClass)
//判断我们这个业务类是否需要被代理,进入isInfrastructureClass代码
//判断Advice、Pointcut、Advisor是否是beanClass的超类或者超接口
//shouldSkip(beanClass, beanName)
//主要是判断beanName不为空且不是original instance
//2个条件都是false 说明需要代理
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);
//如果通知不为空
//protected static final Object[] DO_NOT_PROXY = 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;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey)))判断是否在不需要代理的集合里
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)),这两行判断跟上面的一样,不解释。
如果这两个判断都不成立,下面的代码就是代理的创建!创建!创建!
由于本文只探讨时机,不探讨具体的创建代理的过程的源码,创建代理的过程的源码会在后续文章中更新。