两个生命周期时间与bean关系尤为重要:
postinitialization(初始化后)和predestruction(销毁前)。
(Spring并不管理那些被配置成非单例bean的生命周期)
指定初始化方法:
调用:
实现InitializingBean接口:
Spring中InitializingBean接口允许你在bean的代码中这样定义:你希望bean能接收到Spring已经完成对其配置的通知。就像使用初始化方法时一样,你可以借机检查bean的配置以确保其有效,若要必要,还可以给出默认值。
决议顺序:
Spring首先调用InitializingBean.afterPropertiesSet()方法,然后再调用初始化方法。(建议如果存在顺序,都写入到afterPropertiesSet中调用。)
afterPropertiesSet方法和类的继承:
例子抽象父类实现了接口,但是把afterPropertiesSet定义成了final,不可被子类覆盖,也就是去实现一些通用的初始化,然后再调用了自己定义的initSimple()初始化方法。
父类:
继承:
配置文件:
嵌入bean的销毁:
1、bean销毁时执行某一方法
配置文件:
2、实现DisposableBean接口
DisposableBean接口提供了destory方法。
配置文件:
3、使用关闭钩子
注入关闭代码:
调用代码:
postinitialization(初始化后)和predestruction(销毁前)。
(Spring并不管理那些被配置成非单例bean的生命周期)
指定初始化方法:
- packagecn.partner4java.init;
- /**
- * 指定初始化方法
- * @author partner4java
- *
- */
- publicclassSimpleBean {
- privateString name;
- privateintage =0;
- publicvoidinit(){
- if(name ==null){
- System.out.println("name为空");
- }
- if(age ==0){
- System.out.println("age为0");
- }
- }
- publicString getName() {
- returnname;
- }
- publicvoidsetName(String name) {
- this.name = name;
- }
- publicintgetAge() {
- returnage;
- }
- publicvoidsetAge(intage) {
- this.age = age;
- }
- }
- <?xml version="1.0"encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
- <bean id="simple1"class="cn.partner4java.init.SimpleBean"
- init-method="init">
- <property name="age"value="29"/>
- <property name="name"value="Dr. Jekyll"/>
- </bean>
- <bean id="simple2"class="cn.partner4java.init.SimpleBean"
- init-method="init">
- <property name="age"value="29"/>
- </bean>
- <bean id="simple3"class="cn.partner4java.init.SimpleBean"
- init-method="init">
- <property name="name"value="Mr. Hyde"/>
- </bean>
- </beans>
调用:
- //在调用获取的时候就会调用init,在调用init之前,已经使用控制反转设置方法依赖注入设置进数据
- BeanFactory beanFactory = getBeanFactory();
- System.out.println("simple1");
- beanFactory.getBean("simple1");
- System.out.println("simple2");
- beanFactory.getBean("simple2");
- System.out.println("simple3");
- beanFactory.getBean("simple3");
- //后台打印:
- //simple1
- //simple2
- //name为空
- //simple3
- //age为0
实现InitializingBean接口:
Spring中InitializingBean接口允许你在bean的代码中这样定义:你希望bean能接收到Spring已经完成对其配置的通知。就像使用初始化方法时一样,你可以借机检查bean的配置以确保其有效,若要必要,还可以给出默认值。
- publicclassSimpleBeanIBimplementsInitializingBean {
- privatestaticfinalString DEFAULT_NAME ="Jan Machacek";
- privateString name;
- privateintage =0;
- publicString getName() {
- returnname;
- }
- publicvoidsetName(String name) {
- this.name = name;
- }
- publicintgetAge() {
- returnage;
- }
- publicvoidsetAge(intage) {
- this.age = age;
- }
- @Override
- publicString toString() {
- finalStringBuilder sb =newStringBuilder();
- sb.append("SimpleBean");
- sb.append("{name='").append(name).append('\'');
- sb.append(", age=").append(age);
- sb.append('}');
- returnsb.toString();
- }
- publicvoidafterPropertiesSet()throwsException {
- System.out.println("initializing bean");
- if(this.name ==null) {
- System.out.println("No name specified, using default.");
- this.name = DEFAULT_NAME;
- }
- if(this.age ==0) {
- thrownewIllegalArgumentException("You must set the [age] property bean of type ["+ getClass().getName() +"]");
- }
- }
- }
决议顺序:
Spring首先调用InitializingBean.afterPropertiesSet()方法,然后再调用初始化方法。(建议如果存在顺序,都写入到afterPropertiesSet中调用。)
afterPropertiesSet方法和类的继承:
例子抽象父类实现了接口,但是把afterPropertiesSet定义成了final,不可被子类覆盖,也就是去实现一些通用的初始化,然后再调用了自己定义的initSimple()初始化方法。
父类:
- publicabstractclassSimpleBeanSupportimplementsInitializingBean {
- privateString value;
- /**
- * Subclasses may override this method to perform additional initialization.
- * This method gets invoked after the initialization of the {@link SimpleBeanSupport}
- * completes.
- * @throws Exception If the subclass initialization fails.
- */
- protectedvoidinitSimple()throwsException {
- // do nothing
- }
- publicfinalvoidafterPropertiesSet()throwsException {
- Assert.notNull(this.value,"The [value] property of ["+ getClass().getName() +"] must be set.");
- initSimple();
- }
- publicfinalvoidsetValue(String value) {
- this.value = value;
- }
- protectedfinalString getValue() {
- returnthis.value;
- }
- }
继承:
- publicclassSoutSimpleBeanextendsSimpleBeanSupport {
- privateString person;
- protectedvoidinitSimple()throwsException {
- Assert.notNull(this.person,"The [person] property of ["+ getClass().getName() +"] must be set.");
- }
- publicvoidsetPerson(String person) {
- this.person = person;
- }
- @Override
- publicString toString() {
- returnString.format("%s says \"%s\"",this.person, getValue());
- }
- }
配置文件:
- <?xml version="1.0"encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
- <bean id="simple1"class="com.apress.prospring2.ch04.lifecycle.SoutSimpleBean">
- <property name="person"value="Winston Churchill"/>
- <property name="value"value="This report, by its very length, defends itself against the risk of being read."/>
- </bean>
- </beans>
嵌入bean的销毁:
1、bean销毁时执行某一方法
- publicclassDestructiveBeanimplementsInitializingBean {
- privateInputStream is =null;
- privateString filePath =null;
- publicvoidafterPropertiesSet()throwsException {
- System.out.println("Initializing Bean");
- Assert.notNull(this.filePath,"The [filePath] property of ["+ getClass().getName() +"] must be set.");
- newFile(this.filePath).createNewFile();
- this.is =newFileInputStream(this.filePath);
- }
- publicvoiddestroy() {
- System.out.println("Destroying Bean");
- if(this.is !=null) {
- try{
- this.is.close();
- this.is =null;
- newFile(this.filePath).delete();
- }catch(IOException ex) {
- System.err.println("WARN: An IOException occured"
- +" while trying to close the InputStream");
- }
- }
- }
- publicvoidsetFilePath(String filePath) {
- this.filePath = filePath;
- }
- @Override
- publicString toString() {
- finalStringBuilder sb =newStringBuilder();
- sb.append("DestructiveBean");
- sb.append("{is=").append(is);
- sb.append(", filePath='").append(filePath).append('\'');
- sb.append('}');
- returnsb.toString();
- }
- }
配置文件:
- <?xml version="1.0"encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
- <bean id="destructive"class="com.apress.prospring2.ch04.lifecycle.DestructiveBean"
- destroy-method="destroy">
- <property name="filePath"value="/tmp/prospring25"/>
- </bean>
- </beans>
2、实现DisposableBean接口
DisposableBean接口提供了destory方法。
- publicclassDestructiveBeanIimplementsInitializingBean, DisposableBean {
- privateInputStream is =null;
- privateString filePath =null;
- publicvoidafterPropertiesSet()throwsException {
- System.out.println("Initializing Bean");
- Assert.notNull(this.filePath,"The [filePath] property of ["+ getClass().getName() +"] must be set.");
- newFile(this.filePath).createNewFile();
- this.is =newFileInputStream(this.filePath);
- }
- publicvoiddestroy() {
- System.out.println("Destroying Bean");
- if(this.is !=null) {
- try{
- this.is.close();
- this.is =null;
- newFile(this.filePath).delete();
- }catch(IOException ex) {
- System.err.println("WARN: An IOException occured"
- +" while trying to close the InputStream");
- }
- }
- }
- publicvoidsetFilePath(String filePath) {
- this.filePath = filePath;
- }
- @Override
- publicString toString() {
- finalStringBuilder sb =newStringBuilder();
- sb.append("DestructiveBean");
- sb.append("{is=").append(is);
- sb.append(", filePath='").append(filePath).append('\'');
- sb.append('}');
- returnsb.toString();
- }
- }
配置文件:
- <?xml version="1.0"encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
- <bean id="destructive"class="com.apress.prospring2.ch04.lifecycle.DestructiveBeanI">
- <property name="filePath"value="/tmp/prospring25"/>
- </bean>
- </beans>
3、使用关闭钩子
注入关闭代码:
- publicclassShutdownHookimplementsRunnable {
- privateConfigurableListableBeanFactory beanFactory;
- publicShutdownHook(ConfigurableListableBeanFactory beanFactory) {
- Assert.notNull(beanFactory,"The 'beanFactory' argument must not be null.");
- this.beanFactory = beanFactory;
- }
- publicvoidrun() {
- this.beanFactory.destroySingletons();
- }
- }
调用代码:
- publicclassShutdownHookDemo {
- publicstaticvoidmain(String[] args)throwsIOException {
- XmlBeanFactory factory =newXmlBeanFactory(newClassPathResource("/META-INF/spring/lifecycledemo5-context.xml"));
- Runtime.getRuntime().addShutdownHook(newThread(newShutdownHook(factory)));
- newBufferedInputStream(System.in).read();
- }
- }