咱们可能会在 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);