總結Spring框架擴充套件點(二)bean生命週期中的擴充套件點(持續更新中...)
面向業務開發的時候,程式設計師需要明白業務的邏輯,並設計程式碼結構。而在進行中介軟體開發的時候,則需要明白框架的邏輯,進行開發。
所以要開發提供給spring的中介軟體,需要知道spring中有哪些擴充套件點,好在對應的地方插入我們的功能。
1. Spring容器初始化bean大致過程
1. 定義bean標籤
2. 將bean標籤解析成BeanDefinition
3. 呼叫構造方法例項化(IOC):
4. 屬性值得依賴注入(DI)
2. BeanFactory構造階段
1.1 NamespaceHandler
3. ApplicationContext構造階段
3.1 BeanFactoryPostProcessor
說明:
顧名思義,是BeanFactory的後置處理器,處理的物件是BeanFactory
執行時間:
bean factory已經被standard initialization了
所有的bean definitions已經被家在到bean factory中了
但是還沒有例項化任何的bean,bean的建構函式都沒被執行
註冊方法:
要使用BeanPostProcessor回撥,就必須先在容器中註冊實現該介面的類,那麼如何註冊呢?BeanFactory和ApplicationContext容器的註冊方式不大一樣:若使用BeanFactory,則必須要顯示的呼叫其addBeanPostProcessor()方法進行註冊,引數為BeanPostProcessor實現類的例項;如果是使用ApplicationContext.xml,那麼容器會在配置檔案在中自動尋找實現了BeanPostProcessor介面的Bean,然後自動註冊,我們要做的只是配置一個BeanPostProcessor實現類的Bean就可以了。
一般用途:
獲取相關Bean的bean definition,並修改bean definition
例如:
- 給屬性賦值,修改屬性值
- 可以把bean的scope從singleton改為prototype,也可以把property的值給修改掉。
- 可以同時配置多個BeanFactoryPostProcessor,並通過設定'order'屬性來控制各個BeanFactoryPostProcessor的執行次序
spring內建的BeanFactoryPostProcessor實現類:
- org.springframework.beans.factory.config.PropertyPlaceholderConfigurer:屬性佔位符配置
- org.springframework.beans.factory.config.PropertyOverrideConfigurer:
- org.springframework.beans.factory.config.CustomEditorConfigurer:用來註冊自定義的屬性編輯器
正式應用:
筆者使用的某款知名內部RPC框架中,就是在這個階段,給bean
3.2 BeanPostProcessor
說明:
顧名思義,是Bean的後置處理器,處理的物件是Bean
執行時間:
bean被spring容器例項化之後,即建構函式已經被執行
bean的set方法被呼叫注入屬性值之後
在執行bean的初始化方法的前後。這裡說的初始化方法,指的是下面兩種:
- bean實現了InitializingBean介面,對應的方法為afterPropertiesSet
- 在bean定義的時候,通過init-method設定的方法
如果上述方法都存在的話,執行順序是:
- postProcessBeforeInitialization
- afterPropertiesSet
- init-method
- postProcessAfterInitialization
註冊方法:
跟BeanPostProcessor一樣,ApplicationContext也能自動檢測和呼叫容器中的BeanFactoryPostProcessor。
一般用途:
例如:給bean新增動態代理
spring內建的BeanPostProcessor實現類:
- org.springframework.context.annotation.CommonAnnotationBeanPostProcessor:支援@Resource註解的注入
- org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor:支援@Required註解的注入
- org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor:支援@Autowired註解的注入
- org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor:支援@PersistenceUnit和@PersistenceContext註解的注入
- org.springframework.context.support.ApplicationContextAwareProcessor:用來為bean注入ApplicationContext等容器物件
3.3 系統如何呼叫這幾個方法的
在使用ApplicationContext啟動spring容器的時候,在AbstractApplicationContext.refresh()方法中,完成相關初始化工作:
首先是BeanFactoryPostProcessor鉤子:
在第5步invokeBeanFactoryPostProcessors方法中,呼叫了BeanFactoryPostProcessor.postProcessBeanFactory方法,相關原始碼如下:
/**
* Instantiate and invoke all registered BeanFactoryPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before singleton instantiation.
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// Invoke factory processors registered with the context instance.
for (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) {
BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();
factoryProcessor.postProcessBeanFactory(beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List priorityOrderedPostProcessors = new ArrayList();
List orderedPostProcessorNames = new ArrayList();
List nonOrderedPostProcessorNames = new ArrayList();
for (int i = 0; i < postProcessorNames.length; i++) {
if (isTypeMatch(postProcessorNames[i], PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(postProcessorNames[i]));
}
else if (isTypeMatch(postProcessorNames[i], Ordered.class)) {
orderedPostProcessorNames.add(postProcessorNames[i]);
}
else {
nonOrderedPostProcessorNames.add(postProcessorNames[i]);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
Collections.sort(priorityOrderedPostProcessors, new OrderComparator());
invokeBeanFactoryPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List orderedPostProcessors = new ArrayList();
for (Iterator it = orderedPostProcessorNames.iterator(); it.hasNext();) {
String postProcessorName = (String) it.next();
orderedPostProcessors.add(getBean(postProcessorName));
}
Collections.sort(orderedPostProcessors, new OrderComparator());
invokeBeanFactoryPostProcessors(beanFactory, orderedPostProcessors);
// Finally, invoke all other BeanFactoryPostProcessors.
List nonOrderedPostProcessors = new ArrayList();
for (Iterator it = nonOrderedPostProcessorNames.iterator(); it.hasNext();) {
String postProcessorName = (String) it.next();
nonOrderedPostProcessors.add(getBean(postProcessorName));
}
invokeBeanFactoryPostProcessors(beanFactory, nonOrderedPostProcessors);
}
/**
* Invoke the given BeanFactoryPostProcessor beans.
*/
private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List postProcessors) {
for (Iterator it = postProcessors.iterator(); it.hasNext();) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor) it.next();
postProcessor.postProcessBeanFactory(beanFactory);
}
}
上面的程式碼中,首先通過beanFactory.getBeanNamesForType獲取spring配置檔案中定義的,所有實現BeanFactoryPostProcessor介面的bean,然後根據優先順序進行排序,之後對於每個BeanFactoryPostProcessor,呼叫postProcessBeanFactory方法。
然後是BeanPostProcessor鉤子:
第一種情況,對於prototype型別的bean,第6步中,呼叫registerBeanPostProcessors方法,註冊所有實現BeanPostProcessor介面的bean。然後等到程式執行該bean的getBean方法初始化的時候執行對應的BeanPostProcessor方法。
第二種情況,對於singleton型別的bean,並且不是抽象類,也不延遲初始化,則在第11步中,通過finishBeanFactoryInitialization方法,呼叫getBean方法來例項化bean,從而直接執行BeanPostProcessor方法
可以看到,BeanPostProcessor鉤子都是在bean被getBean方法初始化的時候被執行,只不過getBean方法被執行的時間不同。我們接下來看看getBean方法做了什麼:
getBean方法最終是通過呼叫AbstractAutowireCapableBeanFactory.doCreateBean方法來執行初始化的,該方法的實現如下:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
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);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);
for (int i = 0; i < dependentBeans.length; i++) {
String dependentBean = dependentBeans[i];
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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
我們可以看到,getBean方法中,首先呼叫createBeanInstance方法,建立bean例項物件(這個時候執行bean的構造方法),然後呼叫populateBean方法,對bean進行填充,注入相關依賴,之後再呼叫方法initializeBean,進行相關初始化工作,initializeBean方法的實現如下:
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
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;
}
從上面的實現可以看出,initializeBean先呼叫applyBeanPostProcessorsBeforeInitialization方法,執行每個BeanPostProcessor的postProcessBeforeInitialization,然後呼叫invokeInitMethods方法,執行bean的初始化方法,最後呼叫applyBeanPostProcessorsAfterInitialization方法,執行每個BeanPostProcessor的postProcessAfterInitialization方法。
postProcessBeforeInitialization,applyBeanPostProcessorsAfterInitialization,invokeInitMethods這三個方法的實現如下:
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
}
return result;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
result = beanProcessor.postProcessAfterInitialization(result, beanName);
}
return result;
}
protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
((InitializingBean) bean).afterPropertiesSet();
}
String initMethodName = (mbd != null ? mbd.getInitMethodName() : null);
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, initMethodName, mbd.isEnforceInitMethod());
}
}
重點看一下invokeInitMethods方法,裡面先執行afterPropertiesSet方法,然後再通過反射,執行init-method指定的方法。
一個完整的例子:
a) DestructionAwareBeanPostProcessor
b) InstantiationAwareBeanPostProcessor
c) SmartInstantiationAwareBeanPostProcessor
d) MergedBeanDefinitionPostProcessor
總結:
等待補充