一文了解Spring--Bean生命周期

Bean获取和实例化

ApplicationContext与BeanFactory关系
一文了解Spring--Bean生命周期_第1张图片
ApplicationContext它是扩展BeanFactory接口。
BeanFactory它采取延迟加载的方案,只有真正在getBean时才会实例化Bean

在开发中我们一般使用的是ApplicationContext,真正使用的是其实现类,
FileSystemXmlAppliCationContext 根据文件路径获取
ClassPathXmlApplicationContext 根据类路径获取

AppliCationContext它会在配置文件加载时,就会初始化Bean,并且ApplicationContext它提供不同的应用层的Context实现。例如在web开发中可以使用WebApplicationContext.

IOC获取Bean实例化对象

  • 在applicationContext.xml文件中配置bean
<bean id="userService" class="com.test.userServiceImpl"/>
  • 创建一个AppliCationContext对象
    ApplicationContext它是BeanFactory的一个子接口,我们在使用时使用的是AppliCationContext的实现类ClassPathXmlApplicationContext,获取Spring配置上下文对象
//使用Spring的IOC容器;IOC本质是XML配置文件+反射+BeanFactory来实现
//Soring提供一个BeanFactory工厂统一管理Bean,使用其子接口ApplicationContext
//ClassPathXmlApplicationContext:在类路径下根据参数文件名查找ApplicationContext.xml对象
ApplicationContext application=new ClassPathXmlApplicationContext("ApplicationContext");
UserService userService=(UserService)application.getBean("userService");

Bean的生命周期流程

一文了解Spring--Bean生命周期_第2张图片

  1. instantiate bean 构造方法实例化Bean对象
  2. populate properties 封装属性,di依赖注入
  3. 如果Bean实现BeanNameAware,执行setBeanName,也就是bean的id值
  4. 如果Bean实现BeanFactoryAwar或ApplicationContextAwar,需要设置工厂setBeanFactory或上下文对象setApplicationContext
  5. 如果存在类实现BeanPostProcessor(后处理Bean),执行postProcessBeforeInitialization,可以在初始化之前执行一些方法
  6. 如果Bean实现InitializingBean(初始化)接口,执行afterPropertiesSet方法(相当于自定义init-method),执行属性设置之后的操作
  7. 调用自定义的< bean init-method=" " >初始化方法
  8. 如果存在类实现BeanPostProcessor(处理Bean),执行postProcessAfterInitialization,执行初始化之后的操作
  9. 执行业务处理(Bean可用)
  10. 如果Bean实现DisposableBean执行destroy
  11. 调用自定义的< bean destroy-method=’’ >销毁方法

对于bean的生命周期方法:
第三步与第四步是让Bean了解spring容器。

第五步与第八步 可以针对指定的Bean进行功能增强(在初始化前后执行),这时一般会使用动态代理.

第六步与第十步:通过实现指定的接口来完成init与destroy操作
但是在开发中一般不使用第6步与第10步,原因是我们可以使用第7步与第11步来完成。
第7步与第11步的初始化与销毁操作它无耦合,推荐使用的。但是必须在配置文件中指定初始化与销毁的方法

代码实例:

在xml配置文件中配置相关的bean

<!-- 自定义bean -->
	<bean id="testBean" name="bean1" class="com.dubbox.bean.TestBean" init-method="myInit" destroy-method="myDestroy">
	 <property name="beanStr" value="张三的歌"/>
	 <property name="beanInt" value="123"></property>
	</bean>
	<!-- 实现BeanPostProcessor接口的bean,spring ioc容器扩展 -->
	<bean id="postProcessor" class="com.dubbox.bean.PostProcessor"></bean>
	
	<!-- spring 注解扫描 -->
	<context:component-scan base-package="com.dubbox"></context:component-scan>

Bean分别实现 BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean


/**
 * 
 * @author 张江丰 
 * BeanNameAware: 
 *      实现setBeanName方法 设置Bean的id 
 * ApplicationContextAware/BeanFactoryBean:
 *         实现setApplicationContext/setBeanFactory方法 设置ApplicationComtext上下文对象/BeanFactory
 * BeanPostProcessor: 
 *         实现 postProcessBeforeInitialization 和   postProcessAfterInitialization 分别执行初始化执行之前和之后的方法
 * InitializingBean:
 *         实现afterPropertiesSet方法,进行Bean初始化,在属性封装之后执行
 * DisposableBean: 
 *         实现destroy方法 销毁执行
 *
 */
@Scope(value = "singleton")
public class TestBean implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {

	private String beanStr;

	private Integer beanInt;

	public String getName() {
		return "zhangsan";
	}

	public String getBeanStr() {
		return beanStr;
	}

	public void setBeanStr(String beanStr) {
		this.beanStr = beanStr;
	}

	public Integer getBeanInt() {
		return beanInt;
	}

	public void setBeanInt(Integer beanInt) {
		this.beanInt = beanInt;
	}

	@Override
	public void setBeanName(String name) {
		// TODO Auto-generated method stub
		System.out.println("调用setBeanName方法:" + name);

	}

	private ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext arg0) throws BeansException {
		// TODO Auto-generated method stub
		this.applicationContext = arg0;
		// TestBean bean = (TestBean) applicationContext.getBean("testBean");
		System.out.println("调用setApplicationContext方法,获取Spring容器ApplicationContext对象:" + applicationContext);

	}

	@Override
	public void destroy() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("调用destroy方法,bean被销毁了");

	}

	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		try {
			System.out.println("调用afterPropertiesSet方法,bean初始化执行了");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("bean初始化异常" + e.getMessage());
		}

	}

	//@PostConstruct // 相当于在bean中配置了 init-method="myInit"
	public void myInit() {
		System.out.println("自定义init执行");
	}

	//@PreDestroy // 相当与在bean中配置了 destory-method="myDestroy"
	public void myDestroy() {
		System.out.println("自定义Destory执行");
	}

}

自定义类实现BeanPostProcessor接口,分别实现postProcessBeforeInitialization和postProcessAfterInitialization方法,可以在bean初始化前后执行,需要在xml配置文件中配置,是springIOC容器的扩展
BeanPostProcessor接口也叫后置处理器,作用是在Bean对象在实例化和依赖注入完毕后,在显示调用初始化方法的前后添加我们自己的逻辑。注意是Bean实例化完毕后及依赖注入完成后触发的。

/**
 * BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口
 * 
 * @author 张江丰
 *
 */
public class PostProcessor implements BeanPostProcessor {

	@Override // 在bean初始化之前执行
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof TestBean) {
			System.out.println("调用postProcessBeforeInitialization方法,在初始化init之前执行:" + beanName + "开始实例化");
		}
		// 从spring IOC容器中取出bean,使用后必须返回bean对象
		return bean;
	}

	@Override // 在bean初始化之后执行
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof TestBean) {
			System.out.println("调用postProcessAfterInitialization方法,在初始化init之后执行:" + beanName + "实例化完成");
		}
		// 从spring IOC容器中取出bean,使用后必须返回bean对象
		return bean;
	}

}

junit测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring/applicationContext.xml" })
public class Test1 {

	@Test
	public void demo1() throws Exception {
		ApplicationContext app = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
		TestBean tb = (TestBean) app.getBean("testBean");
		// TestBean tb = new TestBean();
		System.out.println(tb.getBeanStr());
	}

}

控制台输出内容

调用setBeanName方法:testBean
调用setApplicationContext方法,获取Spring容器ApplicationContext对象:org.springframework.context.support.ClassPathXmlApplicationContext@63611043: startup date [Fri Feb 07 12:20:13 CST 2020]; root of context hierarchy
调用postProcessBeforeInitialization方法,在初始化init之前执行:testBean开始实例化
调用afterPropertiesSet方法,bean初始化执行了
自定义init执行
调用postProcessAfterInitialization方法,在初始化init之后执行:testBean实例化完成
张三的歌
调用destroy方法,bean被销毁了
自定义Destory执行

由此可见控制台输出顺序和springbean生命周期流程一致,首先执行实例化bean对象,设置对象属性,检查Aware相关接口,如果有类实现BeanPostProcessor接口,在bean初始化init前后执行扩展方法,bean可用状态.

码字不易,看过的同学请点赞~

你可能感兴趣的:(spring)