目录
1.方式一在注解@bean 添加属性实现bean的初始化和销毁
2.方式二 实现InitializingBean,DisposableBean两个接口来初始化和销毁对象
3.方式三 @PostContruct, @PreDestroy注解实现
一、Bean的生命周期:
bean创建--初始化--使用--销毁 的过程
创建:
- 单实例:IOC容器启动的时候创建对象;
- 多实例:调用一次创建一个对象
初始化:
- 对象创建好后并赋值后,调用初始化方法
销毁:
- 单实例:容器关闭的时候销毁对象;
- 多实例:容器不会管理多实例的,需要手动调用destroy方法
1.方式一在注解@bean 添加属性实现bean的初始化和销毁
以前学习的在xml配置有一个init-method,destroy-method方法实现bean创建和销毁时调用的方法,这里使用init和destory属性。@Bean(value = "user",initMethod = "init",destroyMethod = "destroy") //这里实现和xml配置相似
例子:
1.1对象类:
@Data
@Builder
@AllArgsConstructor
public class User {
private String name;
private Integer age;
public void init(){
System.out.println("init....");
}
public void destroy(){
System.out.println("destroy...");
}
}
1.2 配置类
@Configuration
public class MainLifyCycleConfig {
//@Scope("prototype")
@Bean(value = "user",initMethod = "init",destroyMethod = "destroy") //这里
public User user(){
return new User("vison",23);
}
}
1.3 测试类
public class IOCTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainLifyCycleConfig.class);
Object user = applicationContext.getBean("user");
System.out.println(user);
applicationContext.close();
}
}
结果可以看到在调用user的时候调用了init方法,在容器销毁的时候对调用destroy方法。但是如果@Scope("prototype")注解打开后,就不会调用destroy方法。
2.方式二 实现InitializingBean,DisposableBean两个接口来初始化和销毁对象
InitializingBean 只有一个方法afterPropertiesSet()表示对象的初始化;DisposableBean哟一个方法destroy表示对象的销毁
例子,这里通过扫描的方式来注册bean:
2.1对象类
@Component
public class Task implements InitializingBean,DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Task init ...");
}
@Override
public void destroy() throws Exception {
System.out.println("Task destory.....");
}
}
2.2 配置类:
@ComponentScan(value = "com.wusu.annotation.lifecycle")
@Configuration
public class MainLifyCycleConfig {
@Bean(value = "user",initMethod = "init",destroyMethod = "destroy")
public User user(){
return new User("vison",23);
}
}
2.3 测试
public class IOCTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainLifyCycleConfig.class);
applicationContext.close();
}
}
结果分别调用了相应的方法:
Task init ...
user init....
九月 22, 2018 10:27:25 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@20ad9418: startup date [Sat Sep 22 10:27:25 CST 2018]; root of context hierarchy
user destroy...
Task destory.....
3.方式三 @PostContruct, @PreDestroy注解实现
在JSR250规范
@PostContruct:在创建完对象,并且对象属性赋值完后,来执行初始化方法
@PreDestroy:在容器销毁bean之前通知我们做清理工作
例子:
3.1 对象类:
@Component
public class Scheduler {
@PostConstruct
public void init(){
System.out.println("scheduler postConstruct...");
}
@PreDestroy
public void destroy(){
System.out.println("scheduler preDestroy...");
}
}
同样适用上面的配置和测试类,结果同样实现上面两个相同的功能。
4.BeanPostProcessor 后置处理器
bean的后置处理器,在bean初始化前后处理一些工作,就是在上面三种初始化(init,@PostConstruct,InitializingBean接口)调用的前后做一些工作的处理.。通过这个方法可以对bean进行一些包装和处理
源码:
public interface BeanPostProcessor {
//在任何初始化方法(例如上面的三种方式,定义的init方法,@PostConstruct,接口InitializingBean的方法)调用之前工作
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//这个是在上面的初始化方法调用之后工作
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
例子:
4.1 实现这个接口的类,同样需要放入IOC容器中
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
//这个bean表示刚刚创建的bean,beanName就是这个bean的名字,所以在这里可以包装bean
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("PostBefore bean:"+bean+",beanName:"+beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("PostAfter bean:"+bean+",beanName:"+beanName);
return bean;
}
}
4.2 同样的配置和测试方法结果显示
user 构建中constrctor......
PostBefore bean:User(name=vison, age=23),beanName:user
user init....
PostAfter bean:User(name=vison, age=23),beanName:user
user destroy...
重点---Spring底层对于BeanPostProcessor的使用:
bean赋值,注入其他组件,@AutoWired,生命周期功能,@Async,xxxBeanPostProcess都是使用这个接口的功能来实现。