Bean生命周期

Bean生命周期

基本概述

    生命周期一直是很重要的内容,从以前Java对象、Servlet的生命周期可以看出,只有理解了其生命周期,才能知道应该在哪阶段完成哪阶段的事。Bean被载入到容器的时候,它的生命周期就开始了。

 

 

Bean生命周期

Bean在应用上下文的生命周期

原理图


详细步骤

1实例化(当程序加载applicationContext.xml文件),把bean(前提是scope=singleton)实例化到内存

2调用该BeansetXxx()方法,设置属性。

3如果实现了bean名字关注接口(BeanNameAware),则可以通过setBeanName获取id

4如果实现了bean工厂关注接口(BeanFactoryAware),则可以获取BeanFactory

5如果实现了ApplicationContextAware接口,则可以获得ApplicationContext

6如果bean和一个后置处理器关联,则会自动去调用postProcessBeforeInitialization()方法。

7如果实现InitializingBean接口,则会调用afterPropertiesSet方法。

8如果配置<bean init-method=”init” /> 则可以在bean自定义初始化方法。

9如果bean和一个后置处理器关联,则会自动去调用postProcessAfterInitialization()方法。

10使用bean

11、容器关闭。

12、可以通过实现DisposableBean接口来调用destory()方法。

13、可以在<bean destory-method=”fun1”/> 调用自定义的销毁方法。

PS:实际开发中的流程往往没这么复杂,一般是1->2->6->9->10->11

 

BeanBean工厂的生命周期

    BeanBean工厂的生命周期和在应用上下文的生命周期是不一样的。因为和应用上下文是无关的,所以没有应用上下文中的第5步、第6步和第9步。

 

原理图


案例

Spring配置文件
<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
			http://www.springframework.org/schema/beans 
			http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop 
			http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx 
			http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 在容器文件中配置bean(service/dao/domain/action/数据源) -->
	<bean id="personService" init-method="init" destroy-method="myDestory" class="com.pc.beanlife.PersonService">
		<!-- 这里注入属性,前提是有setName才能成功 -->
		<property name="name" value="zs" />
	</bean>
	<!-- 配置后置处理器(类似filter) -->
	<bean id="myBeanPostProcesseor" class="com.pc.beanlife.MyBeanPostProcesseor" />
</beans>

Bean类文件
package com.pc.beanlife;

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;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
 * 
 * @author Switch
 * @function Bean类
 * @description
 *
 */
public class PersonService implements BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean{
	private String name;
	
	public PersonService() {
		System.out.println("无参构造方法被调用");
	}
	
	public PersonService(String name) {
		System.out.println("有参构造方法被调用");
	}
	
	public void printOk(){
		System.out.println(name + " is Ok");
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		System.out.println("调用set方法设置属性");
		this.name = name;
	}

	// 该方法可以给name表示正被实例化的Bean的id
	@Override
	public void setBeanName(String name) {
		// TODO Auto-generated method stub
		System.out.println("setBeanName 被调用,值是" + name);
	}

	// 该方法可以传递beanFactory
	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("setBeanFactory " + beanFactory);
		
	}

	// 该方法可以设置上下文
	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("setApplicationContext " + applicationContext);
	}

	// 该方法可以在InitializingBean使用
	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("afterPropertiesSet");
	}
	
	// 自定义的初始化方法
	public void init() {
		System.out.println("调用自定义的初始化方法");
	}

	// 可以在这关闭数据连接,socket,文件流,释放资源等等。。。
	@Override
	public void destroy() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("调用destroy()");
	}
	
	// 自定义我们的销毁方法
	public void myDestory() {
		System.out.println("调用自定义的销毁方法");
	}
}

后置处理器文件
package com.pc.beanlife;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
 * 
 * @author Switch
 * @function 后置处理器,相当于Web开发中的过滤器
 * @description 当Bean创建完毕,初始化之前时会调用Before方法,初始化之后会调用After方法
 *
 */
public class MyBeanPostProcesseor implements BeanPostProcessor {
	// 后置处理之后的过滤
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("postProcessBeforeInitialization方法被调用");
		return bean;
	}

	// 后置处理之前的过滤
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("postProcessAfterInitialization方法被调用");
		return bean;
	}
}

测试文件
package com.pc.beanlife;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
/**
 * 
 * @author Switch
 * @function 测试类
 * @description
 *
 */
public class Test {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 通过ApplicationContext加载Bean
		System.out.println("------------在ApplicationContext中Bean的生命周期------------");
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/pc/beanlife/beans.xml");
		// 获取Bean
		PersonService personService = (PersonService) applicationContext.getBean("personService");
		personService.printOk();
		
		// 通过BeanFactory加载Bean
		System.out.println("------------在BeanFactory中Bean的生命周期------------");
		BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("com/pc/beanlife/beans.xml"));
		PersonService personService2 = (PersonService) beanFactory.getBean("personService");
		personService2.printOk();
	}
}

日志文件

------------在ApplicationContext中Bean的生命周期------------
无参构造方法被调用
调用set方法设置属性
setBeanName 被调用,值是personService
setBeanFactory org.springframework.beans.factory.support.DefaultListableBeanFactory@1f8b81e3: defining beans [personService,myBeanPostProcesseor]; 
root of factory hierarchy
setApplicationContext org.springframework.context.support.ClassPathXmlApplicationContext@771c8a71: display name [org.springframework.context.support.
ClassPathXmlApplicationContext@771c8a71]; startup date [Sat Feb 20 11:34:05 CST 2016]; root of context hierarchy
postProcessBeforeInitialization方法被调用
afterPropertiesSet
调用自定义的初始化方法
postProcessAfterInitialization方法被调用
zs is Ok
------------在BeanFactory中Bean的生命周期------------
无参构造方法被调用
调用set方法设置属性
setBeanName 被调用,值是personService
setBeanFactory org.springframework.beans.factory.xml.XmlBeanFactory@6c4fc156: defining beans [personService,myBeanPostProcesseor]; root of factory 
hierarchy
afterPropertiesSet
调用自定义的初始化方法
zs is Ok


PS:通过上面所示Log信息,可以看出BeanApplicationContextBeanFactory中的生命周期是不相同的。


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值