目錄
概述
Spring的核心就是容器思想,後續的所有的spring的功能都是在此基礎上進行擴展,談到擴展我們就不得不提spring爲我們預留的一些功能強大的擴展接口,也就是在設計開發IOC容器的時候爲後續功能或開發者預留的一些接口。
下面我們就來看看spring爲我們預留了哪些接口 他們在容器啓動的哪一步被調用。
BeanPostProcessor
BeanPostProcessor:這是一個所有擴展接口(除BeanFactoryPostProcessor)的父接口。該接口提供兩個方法
- postProcessBeforeInitialization:在對象的初始化之前調用,IOC容器會將當前實例化的對象的引用和名字傳遞給該方法。
- postProcessProperties:在對象的初始化之後調用,IOC容器會將當前正在實例化的對象的引用和名字傳遞給該方法
調用時機
//代碼片段1
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
...略...
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {}
...略...
}
//代碼片段2 上面的initializeBean方法
protected Object initializeBean(final String beanName, final 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()) {
//這裏調用所有 BeanPostProcessor的postProcessBeforeInitialization方法 並把當前的bean的引用和名字傳遞給該方法
//如果有一個後置處理器返回了null 那麼後續的後置處理器將會跳過該方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//這裏實際上就是調用對象的afterPropertiesSet和init方法 順序調用
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
}
if (mbd == null || !mbd.isSynthetic()) {
//這裏調用所有 BeanPostProcessor的postProcessAfterInitialization方法 並把當前的bean的引用和名字傳遞給該方法
//如果有一個後置處理返回了null 後續的後置處理器將會跳過該方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
可以看到上述的兩個方法是在spring實例化Bean的時候調用並且是在bean的初始化前後調用。
InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor:該接口繼承BeanPostProcessor。該接口也提供4個方法 其中一個已廢棄,作用於bean的實例化前後
- postProcessBeforeInstantiation:在對象的實例化之前調用,IOC容器會將當前實例化的Class和名字傳遞給該方法。
- postProcessAfterInstantiation:在對象的實例化之後調用,IOC容器會將當前正在實例化的對象的引用和名字傳遞給該方法
- postProcessProperties: 在對象實例完成之後 初始化之前 可以動態設置實例屬性 可以參考AutowiredAnnotationBeanPostProcessor
調用時機
由於上面兩個方法的調用點 相對比較分散 所以下面將它們分開展示
postProcessBeforeInstantiation:調用點:
//代碼片段1
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
try {
//在這裏調用了postProcessBeforeInstantiation 可以看到這正是實例化bean之前
//下面一個if的條件判斷 意味着 如果我們該方法返回了一個當前class的實例 IOC將結束後面的流程。我們可以在這返回一個代理類。這樣我們就可以動態包裝springIoc容器中的bean
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
}
//實例化bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
//代碼片段2 進入resolveBeforeInstantiation
@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
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
//如果返回了代理類 直接調用postProcessAfterInstantiation並結束實例化流程
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
postProcessAfterInstantiation:調用點:
該調用點分爲兩個地方,第一處是上面代碼調用了postProcessAfterInstantiation ,當postProcessBeforeInstantiation 返回代理類的時候 會立馬執行postProcessAfterInstantiation。
第二處是正常流程實例完之後的調用
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//在填充bean之前調用postProcessAfterInstantiation 如果返回false結束bean的填充和初始化流程
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
}
postProcessProperties調用點
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//這裏調用了屬性填充回調 可以看到是在postProcessAfterInstantiation調用之後
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//該方法已被標記爲廢棄 postProcessProperties取代 這裏僅僅是對該方法做的兼容 相信在後續版本會去掉
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
}
MergedBeanDefinitionPostProcessor
**MergedBeanDefinitionPostProcessor:該接口繼承BeanPostProcessor。該接口提供一個方法,IOC容器會將當前正在實例化的對象的bean定義引用和Class對象以及bean名字傳遞給該方法。
調用時機
以下源碼省略了與本次討論無關的代碼
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//創建bean實例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//這裏調用了 postProcessMergedBeanDefinition 可以看到也是在創建bean實例之後調用 但是在populateBean和initBean之前調用
//所以調用時機應該是介於InstantiationAwareBeanPostProcessor的兩個方法之間。
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
}
mbd.postProcessed = true;
}
}
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");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
}
return exposedObject;
}
SmartInstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor:該接口繼承InstantiationAwareBeanPostProcessor。該接口也提供三個方法,作用於bean的實例化過程
-predictBeanType:從名字看是預測bean的類型。
-determineCandidateConstructors:判斷合適的bean的構造方法。
-getEarlyBeanReference:當bean 創建時,爲了防止後續有循環依賴,會提前暴露回調方法,用於 bean 實例化的後置處理,在提前暴露的回調方法中觸發。
predictBeanType 調用點
//該方法是被isFactoryBean調用 判斷當前實例的Bean是否是FactoryBean 是在創建Bean的實例的方法中調用
@Override
@Nullable
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);
// Apply SmartInstantiationAwareBeanPostProcessors to predict the
// eventual type after a before-instantiation shortcut.
if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
//這裏調用後置處理器的類型預測方法
Class<?> predicted = ibp.predictBeanType(targetType, beanName);
if (predicted != null && (typesToMatch.length != 1 || FactoryBean.class != typesToMatch[0] ||
FactoryBean.class.isAssignableFrom(predicted))) {
return predicted;
}
}
}
}
return targetType;
}
determineCandidateConstructors 調用點
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
...略...
// 該擴展方法也是在bean實例化方法中調用
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
return instantiateBean(beanName, mbd);
}
getEarlyBeanReference調用點
//代碼片段1
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
...略...
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");
}
//這裏在創建完Bean之後 向三級緩存中(singletonFactories)放入一個ObjectFactory對象
//而ObjectFactory回調了SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法得到了一個Bean的早期實例 這也是spring如何解決循環依賴的問題
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
...略...
return exposedObject;
}
//代碼片段2
//這裏是對所有的SmartInstantiationAwareBeanPostProcessor 的getEarlyBeanReference回調
//從singletonFactories獲取緩存的ObjectFactory對象 之後調用 其getObject方法獲取當前的bean實例
//一但調用getObject方法就會執行下面的回調方法 獲取一個提前暴露的bean的引用
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
BeanFactoryPostProcessor
**BeanFactoryPostProcessor:該接口是一個頂級接口。改接口及其子接口一般是對BeanFactory的擴展,一般用來在讀取所有的beanDefinition信息之後,實例化之前可以取修改一些BeanDefinition的信息。提供一個回調方法postProcessBeanFactory:.該方法會將BeanFactory引用傳遞回來。
調用點
// AbstractApplicationContext.refresh
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
//這裏會通過PostProcessorRegistrationDelegate代理類去最終調用postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
catch (BeansException ex) {
}
}
}
BeanDefinitionRegistryPostProcessor
**BeanDefinitionRegistryPostProcessor:該接口是BeanFactoryPostProcessor的一個子接口。該接口也提供了一個擴展方法postProcessBeanDefinitionRegistry 接收一個BeanDefinitionRegistry引用。意味着 我們可以對beanDefinition註冊表去添加刪除更改。
調用點也是在PostProcessorRegistrationDelegate中的invokeBeanFactoryPostProcessors方法中。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//這裏對所有的BeanDefinitionRegistryPostProcessor實現類的postProcessBeanDefinitionRegistry反方調用
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
}
調用執行順序
- BeanDefinitionRegistryPostProcessor:postProcessBeanDefinitionRegistry
- BeanFactoryPostProcessor:postProcessBeanFactory
- InstantiationAwareBeanPostProcessor:postProcessBeforeInstantiation
- SmartInstantiationAwareBeanPostProcessor:determineCandidateConstructors
- MergedBeanDefinitionPostProcessor:postProcessMergedBeanDefinition
- InstantiationAwareBeanPostProcessor:postProcessAfterInstantiation
- SmartInstantiationAwareBeanPostProcessor:getEarlyBeanReference
- InstantiationAwareBeanPostProcessor:postProcessProperties
- BeanPostProcessor:postProcessBeforeInitialization
- BeanPostProcessor:postProcessAfterInitialization