bean的生命周期:指bean的创建---bean的初始化--bean的销毁的过程
一.@Bean指定的初始化和销毁方法
1.以前xml配置文件可以指定init-method,destroy-method
2.@Bean也是指定init-method,destroy-method
创建对象:
单实例:在容器启动的时候创建对象
多实例:在每次获取的时候创建对象
初始化:
在对象创建完成,并复制好,执行初始化方法
销毁:
单实例:容器关闭的时候
多实例:容器不会管理这个bean,容器不会调用销毁方法。可以自己手动调用
写个bean
public class Car {
public Car() {
super();
System.out.println("构建一个car");
}
public void init() {
System.out.println("执行初始化car");
}
public void destroy() {
System.out.println("销毁car");
}
}
配置类,指定初始化和销毁方法
@Configuration
public class MyConfigOfLifeCycle {
@Bean(initMethod="init",destroyMethod="destroy")
public Car car() {
return new Car();
}
}
@Test
public void test() {
//创建容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfigOfLifeCycle.class);
//销毁容器
applicationContext.close();
}
换成多例的实验,会发现容器创建时不会创建对象。只有获取对象时才会创建,并且关闭容器,也不会执行对象的销毁方法
@Configuration
public class MyConfigOfLifeCycle {
@Bean(initMethod="init",destroyMethod="destroy")
@Scope(scopeName="prototype")
public Car car() {
return new Car();
}
}
public void test() {
//创建容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfigOfLifeCycle.class);
Object bean = applicationContext.getBean("car");
//销毁容器
applicationContext.close();
}
二。让Bean 实现InitializingBean接口和DisposableBean接口
定义初始化逻辑
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
定义销毁逻辑
public interface DisposableBean {
void destroy() throws Exception;
}
@Component
public class Cat implements InitializingBean, DisposableBean {
public void destroy() throws Exception {
System.out.println("cat---destroy");
}
public void afterPropertiesSet() throws Exception {
System.out.println("cat---afterPropertiesSet--在属性设置之后");
}
}
@Configuration
@ComponentScans(value= {@ComponentScan("com.melo.bean")})
public class MyConfigOfLifeCycle {
@Bean(initMethod="init",destroyMethod="destroy")
//@Scope(scopeName="prototype")
public Car car() {
return new Car();
}
}
@Test
public void test() {
//创建容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfigOfLifeCycle.class);
//Object bean = applicationContext.getBean("car");
//销毁容器
applicationContext.close();
}
三.@PostConstruct和@PreDestroy
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
JSR250 java规范的注解,@PostConstruct:在bean创建完成并且属性赋值完成后,来执行初始化方法
@PreDestroy:在容器销毁bean之前通知我们进行清理工作
这两个注解是标注在方法上的
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PreDestroy {
}
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Component;
@Component
public class Dog {
public Dog() {
System.out.println("dog构造方法");
}
@PostConstruct
public void init() {
System.out.println("dog @PostConstruct");
}
@PreDestroy
public void destroy() {
System.out.println("dog @PreDestroy");
}
}
四.BeanPostProcessor 后置处理器
在bean初始化前后调用,配置进sping后,会扫描所有bean的创建
postProcessBeforeInitialization在bean初始化之前
postProcessAfterInitialization在bean初始化之后
public interface BeanPostProcessor {
/**
*
* @param bean the new bean instance 新创建实例bean
* @param beanName the name of the bean 实例名
* @return the bean instance to use, either the original or a wrapped one;
* 返回实例或者包装后的实例
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
*
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
*
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
package com.melo.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class MyBeanPostProcess implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization"+beanName+"-->"+bean);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization"+beanName+"-->"+bean);
return bean;
}
}
@Configuration
@ComponentScans(value= {@ComponentScan("com.melo.bean")})
public class MyConfigOfLifeCycle {
@Bean(initMethod="init",destroyMethod="destroy")
//@Scope(scopeName="prototype")
public Car car() {
return new Car();
}
}
@Test
public void test() {
//创建容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfigOfLifeCycle.class);
//Object bean = applicationContext.getBean("car");
//销毁容器
applicationContext.close();
}
配置进sping后,会扫描所有bean的创建。前面几行是spring本身的实例。我们自定义的cat,dog,car,全部是构造方法之后、初始化方法之前执行 postProcessBeforeInitialization,在初始化方法后,销毁方法之前执行postProcessAfterInitialization。
原理:
从上到下的执行链