Spring| Spring的BeanFactoryPostProcessor和BeanPostProcessor

BeanFactoryPostProcessor和BeanPostProcessor,這兩個接口,都是Spring初始化bean時對外暴露的擴展點。兩個接口名稱看起來很相似,但作用及使用場景卻不同,分析如下:

1、BeanFactoryPostProcessor接口

該接口的定義如下:

public interface BeanFactoryPostProcessor {
/**
 * Modify the application context's internal bean factory after its standard
 * initialization. All bean definitions will have been loaded, but no beans
 * will have been instantiated yet. This allows for overriding or adding
 * properties even to eager-initializing beans.
 * @param beanFactory the bean factory used by the application context
 * @throws org.springframework.beans.BeansException in case of errors
 */
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}實現該接口,可以在spring的bean創建之前,修改bean的定義屬性。也就是說,Spring允許BeanFactoryPostProcessor在容器實例化任何其它bean之前讀取配置元數據,並可以根據需要進行修改,例如可以把bean的scope從singleton改爲prototype,也可以把property的值給修改掉。可以同時配置多個BeanFactoryPostProcessor,並通過設置’order’屬性來控制各個BeanFactoryPostProcessor的執行次序。
注意:BeanFactoryPostProcessor是在spring容器加載了bean的定義文件之後,在bean實例化之前執行的。接口方法的入參是ConfigurrableListableBeanFactory,使用該參數,可以獲取到相關bean的定義信息,例子:

1)spring bean的定義:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
	default-autowire="byName">
	
	<bean id="myJavaBean" class="com.ali.caihj.postprocessor.MyJavaBean">
		<property name="desc" value="測試一下啦" />
		<property name="remark" value="這是備註信息啦啦啦" />
	</bean>
	<bean id="myBeanFactoryPostProcessor" class="com.ali.caihj.postprocessor.MyBeanFactoryPostProcessor" />
</beans>

2)自定義的BeanFactoryPostProcessor:

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("調用MyBeanFactoryPostProcessor的postProcessBeanFactory");
        BeanDefinition bd = beanFactory.getBeanDefinition("myJavaBean");
        System.out.println("屬性值============" + bd.getPropertyValues().toString());
        MutablePropertyValues pv =  bd.getPropertyValues();  
        if (pv.contains("remark")) {  
            pv.addPropertyValue("remark", "把備註信息修改一下");  
        }  
        bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
    }

}
spring中,有內置的一些BeanFactoryPostProcessor實現類,常用的有:
  • org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
  • org.springframework.beans.factory.config.PropertyOverrideConfigurer
  • org.springframework.beans.factory.config.CustomEditorConfigurer:用來註冊自定義的屬性編輯器


2、BeanPostProcessor接口

該接口的定義如下:

public interface BeanPostProcessor {

	/**
	 * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
	 * initialization callbacks (like InitializingBean's <code>afterPropertiesSet</code>
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * @param bean the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 */
	Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

	/**
	 * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
	 * initialization callbacks (like InitializingBean's <code>afterPropertiesSet</code>
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
	 * instance and the objects created by the FactoryBean (as of Spring 2.0). The
	 * post-processor can decide whether to apply to either the FactoryBean or created
	 * objects or both through corresponding <code>bean instanceof FactoryBean</code> checks.
	 * <p>This callback will also be invoked after a short-circuiting triggered by a
	 * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
	 * in contrast to all other BeanPostProcessor callbacks.
	 * @param bean the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 * @see org.springframework.beans.factory.FactoryBean
	 */
	Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

}
BeanPostProcessor,可以在spring容器實例化bean之後,在執行bean的初始化方法前後,添加一些自己的處理邏輯。這裏說的初始化方法,指的是下面兩種:

1)bean實現了InitializingBean接口,對應的方法爲afterPropertiesSet

2)在bean定義的時候,通過init-method設置的方法

注意:BeanPostProcessor是在spring容器加載了bean的定義文件並且實例化bean之後執行的。BeanPostProcessor的執行順序是在BeanFactoryPostProcessor之後。

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等容器對象

這些註解類的BeanPostProcessor,在spring配置文件中,可以通過這樣的配置 <context:component-scan base-package="*.*" /> ,自動進行註冊。(spring通過ComponentScanBeanDefinitionParser類來解析該標籤


3、下面通過完整的一個例子,來加深理解

1)定義一個JavaBean

public class MyJavaBean implements InitializingBean {
    private String desc;
    private String remark;
    
    public MyJavaBean() {
        System.out.println("MyJavaBean的構造函數被執行啦");
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        System.out.println("調用setDesc方法");
        this.desc = desc;
    }
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        System.out.println("調用setRemark方法");
        this.remark = remark;
    }
    public void afterPropertiesSet() throws Exception {
        System.out.println("調用afterPropertiesSet方法");
        this.desc = "在初始化方法中修改之後的描述信息";
    }
    public void initMethod() {
        System.out.println("調用initMethod方法");
    }
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("[描述:").append(desc);
        builder.append(", 備註:").append(remark).append("]");
        return builder.toString();
    }
}


2)定義一個BeanFactoryPostProcessor

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("調用MyBeanFactoryPostProcessor的postProcessBeanFactory");
        BeanDefinition bd = beanFactory.getBeanDefinition("myJavaBean");
        MutablePropertyValues pv =  bd.getPropertyValues();  
        if (pv.contains("remark")) {  
            pv.addPropertyValue("remark", "在BeanFactoryPostProcessor中修改之後的備忘信息");  
        }  
    }

}
3)定義一個BeanPostProcessor

public class MyBeanPostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor,對象" + beanName + "調用初始化方法之前的數據: " + bean.toString());
        return bean;
    }
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor,對象" + beanName + "調用初始化方法之後的數據:" + bean.toString());
        return bean;
    }
}
4)spring的配置
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
	default-autowire="byName">
	
	<bean id="myJavaBean" class="com.ali.caihj.postprocessor.MyJavaBean" init-method="initMethod">
		<property name="desc" value="原始的描述信息" />
		<property name="remark" value="原始的備註信息" />
	</bean>
	
	<bean id="myBeanPostProcessor" class="com.ali.caihj.postprocessor.MyBeanPostProcessor" />
	<bean id="myBeanFactoryPostProcessor" class="com.ali.caihj.postprocessor.MyBeanFactoryPostProcessor" />
</beans>

5)測試類

public class PostProcessorMain {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("config/postprocessor.xml");
        MyJavaBean bean = (MyJavaBean) context.getBean("myJavaBean");
        System.out.println("===============下面輸出結果============");
        System.out.println("描述:" + bean.getDesc());
        System.out.println("備註:" + bean.getRemark());

    }
}
6)運行結果如下:


7)分析

從上面的結果可以看出,BeanFactoryPostProcessor在bean實例化之前執行,之後實例化bean(調用構造函數,並調用set方法注入屬性值),然後在調用兩個初始化方法前後,執行了BeanPostProcessor。初始化方法的執行順序是,先執行afterPropertiesSet,再執行init-method。


4、進一步深入分析

在使用ApplicationContext啓動spring容器的時候,在AbstractApplicationContext.refresh()方法中,完成相關初始化工作:


1)BeanFactoryPostProcessor.postProcessBeanFactory,是在第5步執行的,invokeBeanFactoryPostProcessors方法實現如下:

/**
	 * 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(BeanFactoryPostProcessor.class, true, false),獲取spring配置文件中定義的所有實現BeanFactoryPostProcessor接口的bean,然後根據優先級進行排序,之後對於每個BeanFactoryPostProcessor,調用postProcessBeanFactory方法。

2)而BeanPostProcessor的執行,取決於配置文件中bean的定義,如果定義的bean是singleton並且不是抽象類,也不延遲初始化,則BeanPostProcessor是在第11步中執行;而對於prototype的bean,BeanPostProcessor是在程序getBean的時候執行的。在第6步中,調用registerBeanPostProcessors方法,註冊所有實現BeanPostProcessor接口的bean,該方法的實現如下:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors 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, register the BeanPostProcessors that implement PriorityOrdered.
		Collections.sort(priorityOrderedPostProcessors, new OrderComparator());
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors 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());
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Finally, register all other BeanPostProcessors.
		List nonOrderedPostProcessors = new ArrayList();
		for (Iterator it = nonOrderedPostProcessorNames.iterator(); it.hasNext();) {
			String postProcessorName = (String) it.next();
			nonOrderedPostProcessors.add(getBean(postProcessorName));
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
	}

在第11步中,調用finishBeanFactoryInitialization方法,該方法通過調用DefaultListableBeanFactory.preInstantiateSingletons(),進行相關初始化工作:

從上面的代碼可以看出,對於非抽象類、非延遲初始化的單例bean,在spring容器啓動的時候調用getBean方法來實例化bean,並進行相關初始化工作,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;
	}
在該方法中,首先調用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;
	}
從上面的實現可以看出,先調用applyBeanPostProcessorsBeforeInitialization方法,執行每個BeanPostProcessor的postProcessBeforeInitialization,然後調用invokeInitMethods方法,執行bean的初始化方法,最後調用applyBeanPostProcessorsAfterInitialization方法,執行每個BeanPostProcessor的postProcessAfterInitialization方法。這三個方法的實現如下:

	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指定的方法。



參考:https://blog.csdn.net/caihaijiang/article/details/35552859

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章