BeanFactoryPostProcessor
加强出来beanDefinition信息的比如处理${},对配置文件进行解密操作
spring会扫描只B要是实现了beanFactoryPostProcessor接口且注册到容器中的bean都会执行beanFactoryPostProcessor接口中的postProcessBeanDefinitionRegistry方法,如
( PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());源码中的一小段)
invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList();
Iterator var24 = currentRegistryProcessors.iterator();
while(var24.hasNext()) {
ppName = (String)var24.next();
//扫描实现BeanFactoryPostProcessor接口的类--
nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
// 执行invokeBeanFactoryPostProcessors
private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
Iterator var2 = postProcessors.iterator();
while(var2.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();
// 执行postProcessBeanFactory
postProcessor.postProcessBeanFactory(beanFactory);
}
}
例子:
PropertySourcesPlaceholderConfigurer解析替换${}
EncryptablePropertySourceBeanFactoryPostProcessor对配置文件中密码进行密文解密
InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor接口继承beanFactoryPostProcessor
一般作用:给bean一个不需要走bean生命周期实例化流程 的创建bean方式
spring在createBean时有这么一个判断
Object beanInstance;
try {
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var10) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
}
this.resolveBeforeInstantiation(beanName, mbdToUse);会调用到applyBeanPostProcessorsBeforeInstantiation方法
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
Iterator var3 = this.getBeanPostProcessors().iterator();
while(var3.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var3.next();
//可以看到只要实现了applyBeanPostProcessorsBeforeInstantiation接口就执行然后获取到对象直接返回,生命周期无需继续进行
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
BeanPostProcessor
bean的后置处理器,AOP的实现
AbstractApplicationContext中的 registerBeanPostProcessors方法会扫描bean中实现了BeanPostProcessor接口的类。
在bean初始化时会调用该接口的方法(AbstractAutowireCapableBeanFactory的 initializeBean方法)
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//BeanPostProcessor前置方法
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
//BeanPostProcessor后置方法
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
aware
和BeanPostProcessor类似
初始化bean会执行以下方法,如果bean实现了Aware接口就会执行相应的方法。如下代码所示。
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware)bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = this.getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware)bean).setBeanFactory(this);
}
}
}
初始化populateBean方法
填充属性bean的注入
beanFactory和FactoryBean的区别
beanFactory是完成遵行springBean的生命周期的
FactoryBean是不需要遵行生命周期
循环依赖(一二三级缓存)
spring只是解决了单利对象的循环依赖
一级是完整对象(spring中单利bean的实现)
二级是半成品(提前暴露对象引用)
三级是lamda表达式
三级缓存是为AOP考虑的,因为AOP会产生代理对象所以提前暴露的话就要暴露代理对象才对。这里存的是一个函数如果需要提前暴露的话就提前进行AOP,没有调用到提前暴露就等到初始化后在进行AOP操作。
@Async会引起循环依赖问题
三级缓存中有判断【bp instanceof SmartInstantiationAwareBeanPostProcessor】而AsyncAnnotationBeanPostProcessor没有实现SmartInstantiationAwareBeanPostProcessor
相当于三级缓存失效。所以会导致提前暴露的对象不是代理对象从而引发循环依赖问题。
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var5 = this.getBeanPostProcessors().iterator();
while(var5.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var5.next();
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
//对bean进行增强操作后会二次检测。AbstractAutowireCapableBeanFactory的
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException 方法。下面是关键的一部分。
Object exposedObject = bean;
try {
this.populateBean(beanName, mbd, instanceWrapper);
//AOP的bean会生成一个代理对象导致exposedObject != bean.
//如果三级缓存存在循环依赖的会提前进行AOP,这里返回的就还是原来的bean
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
if (earlySingletonExposure) {
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
//@Async生成了代理对象后exposedObject == bean就不成立了。一个是提前暴露的对象,一个是代理对象。
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
//触发循环依赖exception
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.");
}
}
}
}
@Async生成了代理对象后exposedObject == bean就不成立了。一个是提前暴露的对象,一个是代理对象。普通的对象因为实现SmartInstantiationAwareBeanPostProcessor接口存在循环依赖的话就会提前进行AOP不会对bean再次增强所【exposedObject = = bean会成立】
spring事务的传播性
待补充