《spring設計思想》12-InstantationAwareBeanPostProcessor-applyProperties之前回調postProcessProperties

第11節講到InstantiationAwareBeanPostProcessor在bean被Spring“注入”屬性之前將其帶走了,那沒被InstantiationAwareBeanPostProcessor帶走的bean,接下來面對的是什麼呢?

書接上文:回到AbstractAutowireCapableBeanFactory.doCreateBean(String beanName,RootBeanDefinition mbd,Object[] args)

方法:

	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
		。。。
		
		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
            //給至尊寶一個機會,否則注入beanDefinition的屬性
			populateBean(beanName, mbd, instanceWrapper);
            //初始化bean
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		。。。
		return exposedObject;
	}

populateBean(beanName,mbd,instanceWrapper);

這一段代碼是InstantiationAwareBeanPostProcessor在執行完postProcessAfterInstantiation之後。再次執行InstantiationAwareBeanPostProcessor接口的postProcessProperties/postProcessPropertyValues兩個方法:

查看接口定義

	/**
	 * Post-process the given property values before the factory applies them
	 * to the given bean, without any need for property descriptors.
	 * <p>Implementations should return {@code null} (the default) if they provide a custom
	 * {@link #postProcessPropertyValues} implementation, and {@code pvs} otherwise.
	 * In a future version of this interface (with {@link #postProcessPropertyValues} removed),
	 * the default implementation will return the given {@code pvs} as-is directly.
	 * @param pvs the property values that the factory is about to apply (never {@code null})
	 * @param bean the bean instance created, but whose properties have not yet been set
	 * @param beanName the name of the bean
	 * @return the actual property values to apply to the given bean (can be the passed-in
	 * PropertyValues instance), or {@code null} which proceeds with the existing properties
	 * but specifically continues with a call to {@link #postProcessPropertyValues}
	 * (requiring initialized {@code PropertyDescriptor}s for the current bean class)
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @since 5.1
	 * @see #postProcessPropertyValues
	 */
	@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {

		return null;
	}

	/**
	 * Post-process the given property values before the factory applies them
	 * to the given bean. Allows for checking whether all dependencies have been
	 * satisfied, for example based on a "Required" annotation on bean property setters.
	 * <p>Also allows for replacing the property values to apply, typically through
	 * creating a new MutablePropertyValues instance based on the original PropertyValues,
	 * adding or removing specific values.
	 * <p>The default implementation returns the given {@code pvs} as-is.
	 * @param pvs the property values that the factory is about to apply (never {@code null})
	 * @param pds the relevant property descriptors for the target bean (with ignored
	 * dependency types - which the factory handles specifically - already filtered out)
	 * @param bean the bean instance created, but whose properties have not yet been set
	 * @param beanName the name of the bean
	 * @return the actual property values to apply to the given bean (can be the passed-in
	 * PropertyValues instance), or {@code null} to skip property population
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see #postProcessProperties
	 * @see org.springframework.beans.MutablePropertyValues
	 * @deprecated as of 5.1, in favor of {@link #postProcessProperties(PropertyValues, Object, String)}
	 */
	@Deprecated
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		return pvs;
	}

下面的postProcessPropertyValue已經廢棄,推薦使用postProcessProperties方法,在給定的BeanDefinition的屬性被設置到bean裏面之前,可以BeanDefinition中的PropertyValues,看簡單的示例:

獲取到userHolder對象,進行了屬性修改,descript修改成“至尊寶沒帶走我”

原始屬性是:

最終輸出結果

調用堆棧:

綜上所述:在配置的BeanDefinition的propertyValues被設置到bean實例中之前,我們有機會攔截屬性,並更改屬性。

具體方法就是實現InstantiationAwareBeanPostProcessor的postProcessProperties

 

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