一、各種後處理器
1.1、BeanDefinition與BeanFactory擴展
1.1.1、BeanDefinitionRegistryPostProcessor接口
/**
* Extension to the standard {@link BeanFactoryPostProcessor} SPI, allowing for
* the registration of further bean definitions <i>before</i> regular
* BeanFactoryPostProcessor detection kicks in. In particular,
* BeanDefinitionRegistryPostProcessor may register further bean definitions
* which in turn define BeanFactoryPostProcessor instances.
*
* @author Juergen Hoeller
* @since 3.0.1
* @see org.springframework.context.annotation.ConfigurationClassPostProcessor
*/
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
這個接口擴展了標準的BeanFactoryPostProcessor 接口,允許在普通的BeanFactoryPostProcessor接口實現類執行之前註冊更多的BeanDefinition。特別地是,BeanDefinitionRegistryPostProcessor可以註冊BeanFactoryPostProcessor的BeanDefinition。
postProcessBeanDefinitionRegistry方法可以修改在BeanDefinitionRegistry接口實現類中註冊的任意BeanDefinition,也可以增加和刪除BeanDefinition。原因是這個方法執行前所有常規的BeanDefinition已經被加載到BeanDefinitionRegistry接口實現類中,但還沒有bean被實例化。
1.1.2、BeanFactoryPostProcessor接口
BeanFactory生成後,如果想對BeanFactory進行一些處理,該怎麼辦呢?BeanFactoryPostProcessor接口就是用來處理BeanFactory的。
/**
* Allows for custom modification of an application context's bean definitions,
* adapting the bean property values of the context's underlying bean factory.
*
* <p>Application contexts can auto-detect BeanFactoryPostProcessor beans in
* their bean definitions and apply them before any other beans get created.
*
* <p>Useful for custom config files targeted at system administrators that
* override bean properties configured in the application context.
*
* <p>See PropertyResourceConfigurer and its concrete implementations
* for out-of-the-box solutions that address such configuration needs.
*
* <p>A BeanFactoryPostProcessor may interact with and modify bean
* definitions, but never bean instances. Doing so may cause premature bean
* instantiation, violating the container and causing unintended side-effects.
* If bean instance interaction is required, consider implementing
* {@link BeanPostProcessor} instead.
*
* @author Juergen Hoeller
* @since 06.07.2003
* @see BeanPostProcessor
* @see PropertyResourceConfigurer
*/
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;
}
這個接口允許自定義修改應用程序上下文的BeanDefinition,調整上下文的BeanFactory的bean屬性值。應用程序上下文可以在BeanFactory的BeanDefinition中自動檢測BeanFactoryPostProcessor bean,並在創建任何其他bean之前應用它們。對於定位於系統管理員的自定義配置文件非常有用,它們將覆蓋應用程序上下文中配置的bean屬性。請參閱PropertyResourceConfigurer及其具體實現,瞭解解決此類配置需求的開箱即用解決方案。BeanFactoryPostProcessor可能與bean定義交互並修改,但永遠不應該將bean實例化。 這樣做可能會導致過早的bean實例化,違反容器執行順序並導致意想不到的副作用。如果需要bean實例交互,請考慮實現BeanPostProcessor接口。
postProcessBeanFactory方法在BeanFactory初始化後,所有的bean定義都被加載,但是沒有bean會被實例化時,允許重寫或添加屬性。
1.2、Bean實例化中的擴展
1.2.1、BeanPostProcessor接口
/**
* Factory hook that allows for custom modification of new bean instances,
* e.g. checking for marker interfaces or wrapping them with proxies.
*
* <p>ApplicationContexts can autodetect BeanPostProcessor beans in their
* bean definitions and apply them to any beans subsequently created.
* Plain bean factories allow for programmatic registration of post-processors,
* applying to all beans created through this factory.
*
* <p>Typically, post-processors that populate beans via marker interfaces
* or the like will implement {@link #postProcessBeforeInitialization},
* while post-processors that wrap beans with proxies will normally
* implement {@link #postProcessAfterInitialization}.
*
* @author Juergen Hoeller
* @since 10.10.2003
* @see InstantiationAwareBeanPostProcessor
* @see DestructionAwareBeanPostProcessor
* @see ConfigurableBeanFactory#addBeanPostProcessor
* @see BeanFactoryPostProcessor
*/
public interface BeanPostProcessor {
/**
* Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* 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;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @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}
* 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} 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;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @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;
}
這個接口,允許自定義修改新的bean實例,例如檢查標記接口或用代理包裝,注意,如果有相互依賴的bean,這裏可能無法使用代理。
postProcessBeforeInitialization方法,在任何bean初始化回調(如InitializingBean的afterPropertiesSet或自定義init方法)之前,將此BeanPostProcessor應用於給定的新的bean實例。 這個bean已經被填充了屬性值。 返回的bean實例可能是原始的包裝器。
postProcessAfterInitialization方法,在Bean初始化回調(如InitializingBean的afterPropertiesSet或自定義init方法)之後,將此BeanPostProcessor應用於給定的新bean實例。 這個bean已經被填充了屬性值。 返回的bean實例可能是原始的包裝器。這個方法也會在InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法生成對象後再次不讓他生成對象(具體可以參考Spring生成bean的過程)。
二、用來感知IOC容器的各種Aware擴展
2.1、BeanNameAware
實現該接口並重寫void setBeanName(String var1)方法;獲取該bean在BeanFactory配置中的名字
2.2、ApplicationContextAware
實現該接口,並重寫setApplicationContext(ApplicationContext applicationContext)方法,獲取spring 上下文環境的對象,然後通過該上下文對象獲取spring容器中的bean對象
2.3、BeanFactoryAware
實現該接口,並重寫void setBeanFactory(BeanFactory beanFactory) 方法,Bean獲取配置他們的BeanFactory的引用
2.4、ServletContextAware
實現該接口,並重寫void setServletContext(ServletContext servletContext)方法;獲取servletContext容器。
2.5、ResourceLoaderAware
實現該接口,並重寫void setServletContext(ServletContext servletContext)方法;獲取ResourceLoader對象,便能夠通過它獲得各種資源。