postinitialization(初始化后)和predestruction(销毁前)。
(Spring并不管理那些被配置成非单例bean的生命周期)
指定初始化方法:
- package cn.partner4java.init;
- /**
- * 指定初始化方法
- * @author partner4java
- *
- */
- public class SimpleBean {
- private String name;
- private int age = 0;
- public void init(){
- if(name == null){
- System.out.println("name为空");
- }
- if(age == 0){
- System.out.println("age为0");
- }
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- 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的配置以确保其有效,若要必要,还可以给出默认值。
- public class SimpleBeanIB implements InitializingBean {
- private static final String DEFAULT_NAME = "Jan Machacek";
- private String name;
- private int age = 0;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("SimpleBean");
- sb.append("{name='").append(name).append('\'');
- sb.append(", age=").append(age);
- sb.append('}');
- return sb.toString();
- }
- public void afterPropertiesSet() throws Exception {
- 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) {
- throw new IllegalArgumentException("You must set the [age] property bean of type [" + getClass().getName() + "]");
- }
- }
- }
决议顺序:
Spring首先调用InitializingBean.afterPropertiesSet()方法,然后再调用初始化方法。(建议如果存在顺序,都写入到afterPropertiesSet中调用。)
afterPropertiesSet方法和类的继承:
例子抽象父类实现了接口,但是把afterPropertiesSet定义成了final,不可被子类覆盖,也就是去实现一些通用的初始化,然后再调用了自己定义的initSimple()初始化方法。
父类:
- public abstract class SimpleBeanSupport implements InitializingBean {
- private String 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.
- */
- protected void initSimple() throws Exception {
- // do nothing
- }
- public final void afterPropertiesSet() throws Exception {
- Assert.notNull(this.value, "The [value] property of [" + getClass().getName() + "] must be set.");
- initSimple();
- }
- public final void setValue(String value) {
- this.value = value;
- }
- protected final String getValue() {
- return this.value;
- }
- }
继承:
- public class SoutSimpleBean extends SimpleBeanSupport {
- private String person;
- protected void initSimple() throws Exception {
- Assert.notNull(this.person, "The [person] property of [" + getClass().getName() + "] must be set.");
- }
- public void setPerson(String person) {
- this.person = person;
- }
- @Override
- public String toString() {
- return String.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销毁时执行某一方法
- public class DestructiveBean implements InitializingBean {
- private InputStream is = null;
- private String filePath = null;
- public void afterPropertiesSet() throws Exception {
- System.out.println("Initializing Bean");
- Assert.notNull(this.filePath, "The [filePath] property of [" + getClass().getName() + "] must be set.");
- new File(this.filePath).createNewFile();
- this.is = new FileInputStream(this.filePath);
- }
- public void destroy() {
- System.out.println("Destroying Bean");
- if (this.is != null) {
- try {
- this.is.close();
- this.is = null;
- new File(this.filePath).delete();
- } catch (IOException ex) {
- System.err.println("WARN: An IOException occured"
- + " while trying to close the InputStream");
- }
- }
- }
- public void setFilePath(String filePath) {
- this.filePath = filePath;
- }
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("DestructiveBean");
- sb.append("{is=").append(is);
- sb.append(", filePath='").append(filePath).append('\'');
- sb.append('}');
- return sb.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方法。
- public class DestructiveBeanI implements InitializingBean, DisposableBean {
- private InputStream is = null;
- private String filePath = null;
- public void afterPropertiesSet() throws Exception {
- System.out.println("Initializing Bean");
- Assert.notNull(this.filePath, "The [filePath] property of [" + getClass().getName() + "] must be set.");
- new File(this.filePath).createNewFile();
- this.is = new FileInputStream(this.filePath);
- }
- public void destroy() {
- System.out.println("Destroying Bean");
- if (this.is != null) {
- try {
- this.is.close();
- this.is = null;
- new File(this.filePath).delete();
- } catch (IOException ex) {
- System.err.println("WARN: An IOException occured"
- + " while trying to close the InputStream");
- }
- }
- }
- public void setFilePath(String filePath) {
- this.filePath = filePath;
- }
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("DestructiveBean");
- sb.append("{is=").append(is);
- sb.append(", filePath='").append(filePath).append('\'');
- sb.append('}');
- return sb.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、使用关闭钩子
注入关闭代码:
- public class ShutdownHook implements Runnable {
- private ConfigurableListableBeanFactory beanFactory;
- public ShutdownHook(ConfigurableListableBeanFactory beanFactory) {
- Assert.notNull(beanFactory, "The 'beanFactory' argument must not be null.");
- this.beanFactory = beanFactory;
- }
- public void run() {
- this.beanFactory.destroySingletons();
- }
- }
调用代码:
- public class ShutdownHookDemo {
- public static void main(String[] args) throws IOException {
- XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("/META-INF/spring/lifecycledemo5-context.xml"));
- Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook(factory)));
- new BufferedInputStream(System.in).read();
- }
- }