接口 | 方法 | 说明 |
---|---|---|
BeanFactoryPostProcessor | postProcessBeanFactory | 在Bean对象实例化之前执行, 通过beanFactory可以获取bean的定义信息, 并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别 |
BeanPostProcessor | postProcessBeforeInitialization | 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务 |
postProcessAfterInitialization | 实例化、依赖注入、初始化完毕时执行 | |
InstantiationAwareBeanPostProcessor | postProcessBeforeInstantiation | 在方法实例化之前执行,返回结果为null正常执行,返回结果如果不为null则会跳过相关方法而进入初始化完成后的流程 |
postProcessAfterInstantiation | 在方法实例化之后执行,返回结果true才会执行postProcessPropertyValues方法 | |
postProcessPropertyValues | 可以用来修改Bean中属性的内容 | |
InitializingBean | afterPropertiesSet | 初始化的方法 |
DisposableBean | destroy | 容器销毁前的回调方法 |
Aware | setXXX | 感知对应Spring容器的内容 |
@PostConstruct | 标注在方法头部,表示初始化的方法 | |
@PreDestroy | 标注在方法头部,表示销毁前回调的方法 | |
init-method属性 | 指定初始化的方法 | |
destory-method属性 | 指定销毁前的回调方法 |
该接口中的方法是最先执行的。在Bean实例化之前执行
/** * 自定义BeanFactoryPostProcessor * * @author dengp * */ public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { /** * 本方法在Bean对象实例化之前执行, * 通过beanFactory可以获取bean的定义信息, * 并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别 */ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("****** BeanFactoryPostProcessor 开始执行了"); /*String[] names = beanFactory.getBeanDefinitionNames(); for (String name : names) { if("user".equals(name)){ BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name); MutablePropertyValues propertyValues = beanDefinition.getPropertyValues(); // MutablePropertyValues如果设置了相关属性,可以修改,如果没有设置则可以添加相关属性信息 if(propertyValues.contains("name")){ propertyValues.addPropertyValue("name", "bobo"); System.out.println("修改了属性信息"); } } }*/ System.out.println("******* BeanFactoryPostProcessor 执行结束了"); } } 复制代码
该接口中定义了两个方法,分别在Bean对象实例化及装配后在初始化的前后执行
/** * 自定义BeanPostProcessor实现类 * BeanPostProcessor接口的作用是: * 我们可以通过该接口中的方法在bean实例化、配置以及其他初始化方法前后添加一些我们自己的逻辑 * @author dengp * */ public class MyBeanPostProcessor implements BeanPostProcessor{ /** * 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务 * 注意:方法返回值不能为null * 如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象 * 因为后置处理器从Spring IoC容器中取出bean实例对象没有再次放回IoC容器中 */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if("user".equals(beanName)){ System.out.println(">>后置处理器 before方法:"+bean+"/t"+beanName); } // 可以根据beanName不同执行不同的处理操作 return bean; } /** * 实例化、依赖注入、初始化完毕时执行 * 注意:方法返回值不能为null * 如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象 * 因为后置处理器从Spring IoC容器中取出bean实例对象没有再次放回IoC容器中 */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if("user".equals(beanName)){ System.out.println("<<后置处理器after方法:"+bean+"/t"+beanName); } // 可以根据beanName不同执行不同的处理操作 return bean; } } 复制代码
该接口是BeanPostProcessor接口的子接口,所以该接口肯定具有BeanPostProcessor接口的功能,同时又定义了三个自己的接口,这三个接口是在Bean实例化前后执行的方法。
/** * 自定义处理器 * @author dengp * */ public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor{ /** * BeanPostProcessor接口中的方法 * 在Bean的自定义初始化方法之前执行 * Bean对象已经存在了 */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { // TODO Auto-generated method stub if("user".equals(beanName)){ System.out.println("【---InstantiationAwareBeanPostProcessor---】 postProcessBeforeInitialization"); } return bean; } /** * BeanPostProcessor接口中的方法 * 在Bean的自定义初始化方法执行完成之后执行 * Bean对象已经存在了 */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if("user".equals(beanName)){ System.out.println("【--InstantiationAwareBeanPostProcessor----】 postProcessAfterInitialization"); } return bean; } /** * InstantiationAwareBeanPostProcessor中自定义的方法 * 在方法实例化之前执行 Bean对象还没有 */ @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if("user".equals(beanName)){ System.out.println("【--InstantiationAwareBeanPostProcessor----】postProcessBeforeInstantiation"); } return null; } /** * InstantiationAwareBeanPostProcessor中自定义的方法 * 在方法实例化之后执行 Bean对象已经创建出来了 */ @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if("user".equals(beanName)){ System.out.println("【--InstantiationAwareBeanPostProcessor----】postProcessAfterInstantiation"); } return true; } /** * InstantiationAwareBeanPostProcessor中自定义的方法 * 可以用来修改Bean中属性的内容 */ @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { if("user".equals(beanName)){ System.out.println("【--InstantiationAwareBeanPostProcessor----】postProcessPropertyValues--->"); } return pvs; } } 复制代码
Aware接口是用来让对象感知当前的IOC环境
这两个接口是Bean初始化及销毁回调的方法。
package com.dpb.pojo; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; /** * 实现InitializingBean和DisposableBean接口 * @author dengp * */ public class User implements InitializingBean,DisposableBean,BeanNameAware,BeanFactoryAware{ private int id; private String name; //感知本对象在Spring容器中的id属性 private String beanName; // 感知本对象所属的BeanFactory对象 private BeanFactory factory; public User(){ System.out.println("构造方法被执行了...User 被实例化"); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { System.out.println("《注入属性》注入name属性"+name); this.name = name; } public String getBeanName() { return beanName; } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", beanName=" + beanName + "]"; } /** * bean对象销毁前的回调方法 */ @Override public void destroy() throws Exception { // TODO Auto-generated method stub System.out.println("《DisposableBean接口》destory ...."); } /** * 初始化的方法 */ @Override public void afterPropertiesSet() throws Exception { System.out.println("初始化:《InitializingBean接口》afterPropertiesSet...."); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { // TODO Auto-generated method stub System.out.println("【BeanFactoryAware接口】setBeanFactory"); this.factory = beanFactory; } @Override public void setBeanName(String name) { System.out.println("【BeanNameWare接口】setBeanName"); this.beanName = name; } public BeanFactory getFactory() { return factory; } /** * 也是个初始化的方法 */ @PostConstruct public void postConstruct(){ System.out.println("初始化:【@PostConstruct】执行了..."); } /** * 销毁前的回调方法 */ @PreDestroy public void preDestory(){ System.out.println("【@preDestory】执行了..."); } /** * 初始化的方法 * 通过bean标签中的 init-method属性指定 */ public void start(){ System.out.println("初始化:【init-method】方法执行了...."); } /** * 销毁前的回调方法 * 通过bean标签中的 destory-method属性指定 */ public void stop(){ System.out.println("【destory-method】方法执行了...."); } } 复制代码
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <context:annotation-config/> <bean class="com.dpb.pojo.User" id="user" init-method="start" destroy-method="stop" > <property name="name" value="波波烤鸭"></property> </bean> <!-- 注册后置处理器 --> <bean class="com.dpb.processor.MyBeanPostProcessor"/> <!-- 注册 InstantiationAwareBeanPostProcessor --> <bean class="com.dpb.processor.MyInstantiationAwareBeanPostProcessor"></bean> <!-- 注册 BeanFactoryPostProcessor对象--> <bean class="com.dpb.factoryprocessor.MyBeanFactoryPostProcessor"/> </beans> 复制代码
@Test public void test1() { System.out.println("Spring容器开始加载...."); ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = ac.getBean(User.class); System.out.println("---------------"+user); ac.registerShutdownHook(); System.out.println("Spring容器卸载完成...."); } 复制代码
Spring容器开始加载.... 三月 04, 2019 11:14:38 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@707f7052: startup date [Mon Mar 04 23:14:38 CST 2019]; root of context hierarchy 三月 04, 2019 11:14:39 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [applicationContext.xml] ****** BeanFactoryPostProcessor 开始执行了 ******* BeanFactoryPostProcessor 执行结束了 【--InstantiationAwareBeanPostProcessor----】postProcessBeforeInstantiation 构造方法被执行了...User 被实例化 【--InstantiationAwareBeanPostProcessor----】postProcessAfterInstantiation 【--InstantiationAwareBeanPostProcessor----】postProcessPropertyValues---> 《注入属性》注入name属性波波烤鸭 【BeanNameWare接口】setBeanName 【BeanFactoryAware接口】setBeanFactory >>后置处理器 before方法:User [id=0, name=波波烤鸭, beanName=user] user 【---InstantiationAwareBeanPostProcessor---】 postProcessBeforeInitialization 初始化:【@PostConstruct】执行了... 初始化:《InitializingBean接口》afterPropertiesSet.... 初始化:【init-method】方法执行了.... <<后置处理器after方法:User [id=0, name=波波烤鸭, beanName=user] user 【--InstantiationAwareBeanPostProcessor----】 postProcessAfterInitialization ---------------User [id=0, name=波波烤鸭, beanName=user] Spring容器卸载完成.... 三月 04, 2019 11:14:39 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose 信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@707f7052: startup date [Mon Mar 04 23:14:38 CST 2019]; root of context hierarchy 【@preDestory】执行了... 《DisposableBean接口》destroy .... 【destory-method】方法执行了.... 复制代码