咱們可能會在 Bean 對象建立完成後, 執行某些操做或在銷燬前作某些操做.java
咱們能夠實現 InitializingBean
或 DisposableBean
接口數組
public class Test implements InitializingBean, DisposableBean { @Override public void afterPropertiesSet() throws Exception { } @Override public void destroy() throws Exception { } }
固然咱們可使用註解來實現框架
@PostConstruct public void afterPropertiesSet() throws Exception { System.out.println("-- init --"); } @PreDestroy public void destroy() throws Exception { System.out.println("-- destroy --"); }
還有另外一種方法可使用 @Bean
註解ide
public void afterPropertiesSet() throws Exception { System.out.println("-- init --"); } public void destroy() throws Exception { System.out.println("-- destroy --"); } @Bean(initMethod = "afterPropertiesSet", destroyMethod = "destroy") public Test getTest() { return new Test(); }
要注意的是, 初始化和銷燬的方法只是針對當前的 bean 不會對其它 bean 產生影響. post
若是想全部的 bean 在建立前或建立後添加一些處理邏輯, 可使用 BeanPostProcessor
接口. 也能夠配合 Ordered
接口來設置執行順序.代理
若是有兩個容器, 他們之間不會相互影響.
BeanPostProcessor
接口由兩個回調方法組成.code
public interface BeanPostProcessor { // 初始化以前的操做 Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; // 初始化以後的操做 Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
四個子接口:對象
1.DestructionAwareBeanPostProcessor繼承
// 該方法是bean在Spring在容器中被銷燬以前調用 void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
2.InstantiationAwareBeanPostProcessor接口
// postProcessBeforeInstantiation方法的做用在目標對象被實例化以前調用的方法,能夠返回目標實例的一個代理用來代替目標實例 // beanClass參數表示目標對象的類型,beanName是目標實例在Spring容器中的name // 返回值類型是Object,若是返回的是非null對象,接下來除了postProcessAfterInitialization方法會被執行之外,其它bean構造的那些方法都再也不執行。不然那些過程以及postProcessAfterInitialization方法都會執行 Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException; // postProcessAfterInstantiation方法的做用在目標對象被實例化以後而且在屬性值被populate以前調用 // bean參數是目標實例(這個時候目標對象已經被實例化可是該實例的屬性尚未被設置),beanName是目標實例在Spring容器中的name // 返回值是boolean類型,若是返回true,目標實例內部的返回值會被populate,不然populate這個過程會被忽視 boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException; // postProcessPropertyValues方法的做用在屬性中被設置到目標實例以前調用,能夠修改屬性的設置 // pvs參數表示參數屬性值(從BeanDefinition中獲取),pds表明參數的描述信息(好比參數名,類型等描述信息),bean參數是目標實例,beanName是目標實例在Spring容器中的name // 返回值是PropertyValues,可使用一個全新的PropertyValues代替原先的PropertyValues用來覆蓋屬性設置或者直接在參數pvs上修改。若是返回值是null,那麼會忽略屬性設置這個過程(全部屬性不論使用什麼註解,最後都是null) PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;
注: 此接口爲專用接口, 主要用於框架內部使用. 建議儘量地實現普通 BeanPostProcessor 接口, 或 InstantiationAwareBeanPostProcessorAdapter 派生, 以免擴展到該接口.
3.SmartInstantiationAwareBeanPostProcessor
// 預測Bean的類型,返回第一個預測成功的Class類型,若是不能預測返回null Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException; // 選擇合適的構造器,好比目標對象有多個構造器,在這裏能夠進行一些定製化,選擇合適的構造器 // beanClass參數表示目標實例的類型,beanName是目標實例在Spring容器中的name // 返回值是個構造器數組,若是返回null,會執行下一個PostProcessor的determineCandidateConstructors方法;不然選取該PostProcessor選擇的構造器 Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException; // 得到提早暴露的bean引用。主要用於解決循環引用的問題 // 只有單例對象纔會調用此方法 Object getEarlyBeanReference(Object bean, String beanName) throws BeansException;
4.MergedBeanDefinitionPostProcessor
// 該方法是bean在合併Bean定義以後調用 void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);