最近在重新学习spring优秀的框架,顺便记录一下自己的总结,同时分享给大家。bean的生命周期指的是:bean创建–>初始化–>销毁 的过程,bean的生命周期由容器进行管理,我们可以自定义bean的初始化和销毁方法来满足我们的需求,当容器在bean进行到当前生命周期的时候,来调用自定义的初始化和销毁方法。今天主要讲解如何定义初始化和销毁的4中方法。
1,使用initMethod和destroyMethod
下面代码全部是通过配置类,而不是配置xml文件
Train.java
package cap5.bean;
public class Train {
public Train() {
// TODO Auto-generated constructor stub
super();
System.out.println("Train创建");
}
public void init() {
System.out.println("train init...");
}
public void destroy() {
System.out.println("train destroy");
}
}
MainConfig.java
package cap5.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import cap5.bean.Bike;
import cap5.bean.Jeep;
import cap5.bean.TaolongBeanPostProcessor;
import cap5.bean.Train;
//@ComponentScan(value= {"cap5.bean"},includeFilters= {@Filter(type=FilterType.ASSIGNABLE_TYPE,classes=TaolongBeanPostProcessor.class)})
@Configuration
public class MainConfig {
@Bean(initMethod="init",destroyMethod="destroy")
public Train train() {
return new Train();
}
/*@Bean
public Bike bike() {
return new Bike();
}*/
/*@Bean
public Jeep jeep() {
return new Jeep();
}*/
}
MainTest.java
package cap5.test;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import cap5.config.MainConfig;
public class MainTest {
@Test
public void test() {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("IOC 容器创建完成");
System.out.println("IOC 容易准备关闭");
/*String[] names = app.getBeanDefinitionNames();
for(String name:names) {
System.out.println("name="+name);
}*/
app.close();
}
}
打印结果:
2,让bean实现InitializingBean和DisposableBean接口,然后分别实现afterPropertiesSet()方法和destroy()方法
afterPropertiesSet():从名字上就能看出,这个其实不是bean真正的初始化方法,而是在bean构建完成,设置好了属性之后调用的方法—–作用相当于初始化方法
destroy():当bean销毁时,会把单实例bean进行销毁
Bike.java
package cap5.bean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class Bike implements InitializingBean,DisposableBean{
public Bike() {
// TODO Auto-generated constructor stub
super();
System.out.println("bike construct...");
}
public void destroy() throws Exception {
// TODO Auto-generated method stub
System.out.println("bike destroy");
}
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
System.out.println("bike init...");
}
}
MainConfig.java
package cap5.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import cap5.bean.Bike;
import cap5.bean.Jeep;
import cap5.bean.TaolongBeanPostProcessor;
import cap5.bean.Train;
//@ComponentScan(value= {"cap5.bean"},includeFilters= {@Filter(type=FilterType.ASSIGNABLE_TYPE,classes=TaolongBeanPostProcessor.class)})
@Configuration
public class MainConfig {
/*@Bean(initMethod="init",destroyMethod="destroy")
public Train train() {
return new Train();
}*/
@Bean
public Bike bike() {
return new Bike();
}
/*@Bean
public Jeep jeep() {
return new Jeep();
}*/
}
MainTest.java和上面的一样,就不再贴上来了
测试结果:
3,使用JSR250规则定义的注解来实现,JSR250的详细了解可自行百度,主要使用如下两个注解
@PostConstruct:从名字上也能看出这个注解的意思,就是在bean构建完成之后调用—相当于初始化
@PreDestroy:从名字上也能看出是在beandestroy之前会执行的被注解的方法—相当于销毁
Jeep.java
package cap5.bean;
import javax.annotation.*;
public class Jeep {
public Jeep() {
// TODO Auto-generated constructor stub
super();
System.out.println("jeep construct...");
}
@PostConstruct
public void init() {
System.out.println("jeep init...");
}
@PreDestroy
public void destroy() {
System.out.println("jeep destroy...");
}
}
MainConfig.java
package cap5.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import cap5.bean.Bike;
import cap5.bean.Jeep;
import cap5.bean.TaolongBeanPostProcessor;
import cap5.bean.Train;
//@ComponentScan(value= {"cap5.bean"},includeFilters= {@Filter(type=FilterType.ASSIGNABLE_TYPE,classes=TaolongBeanPostProcessor.class)})
@Configuration
public class MainConfig {
/*@Bean(initMethod="init",destroyMethod="destroy")
public Train train() {
return new Train();
}*/
/*@Bean
public Bike bike() {
return new Bike();
}*/
@Bean
public Jeep jeep() {
return new Jeep();
}
}
MainTest.java和上面一样,不重新贴了
运行结果:
4,第四种方法是使用后置处理器,在bean初始化前后时会调用实现了BeanPostProcessor接口并重写两个方法,分别是:postProcessBeforeInitialization()和postProcessAfterInitialization()方法
TaolongBeanPostProcessor.java
package cap5.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class TaolongBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("bean-----"+beanName+" init start...");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("bean------"+beanName+" init end...");
return bean;
}
}
Plane.java
package cap5.bean;
public class Plane {
public Plane() {
// TODO Auto-generated constructor stub
System.out.println("plane construct...");
}
}
MainConfig.java
package cap5.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import cap5.bean.Bike;
import cap5.bean.Jeep;
import cap5.bean.Plane;
import cap5.bean.TaolongBeanPostProcessor;
import cap5.bean.Train;
//@ComponentScan(value= {"cap5.bean"},includeFilters= {@Filter(type=FilterType.ASSIGNABLE_TYPE,classes=TaolongBeanPostProcessor.class)})
@Configuration
public class MainConfig {
/*@Bean(initMethod="init",destroyMethod="destroy")
public Train train() {
return new Train();
}*/
/*@Bean
public Bike bike() {
return new Bike();
}*/
/*@Bean
public Jeep jeep() {
return new Jeep();
}*/
@Bean
public Plane plane() {
return new Plane();
}
@Bean
public TaolongBeanPostProcessor taolongBeanPostProcessor() {
return new TaolongBeanPostProcessor();
}
}
测试效果:
上面都是默认情况下的单例的bean模式,加入在多个bean的情况下呢?容器如何管理bean的生命周期呢?
(1)当bean是多实例的模式下,bean不会在IOC容器创建的时候,去实例化bean,而是在真正使用该bean的时候实例化,这一点可以进行简单的测试一下,当增加@scope(”protorype“)时,就是多实例创建bean了
(2)当容器关闭的时候,多实例的情况下怎么处理,会不会将多个实例同时销毁呢?
我们来简单的测试一下:
MainConfig.java部分代码
@Scope("prototype")
@Bean
public Bike bike() {
return new Bike();
}
MianTest.java
package cap5.test;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import cap5.bean.Bike;
import cap5.config.MainConfig;
public class MainTest {
@Test
public void test() {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("IOC 容器创建完成");
Bike bike1 = (Bike)app.getBean(Bike.class);
Bike bike2 = (Bike)app.getBean(Bike.class);
System.out.println(bike1==bike2);
System.out.println("IOC 容易准备关闭");
/*String[] names = app.getBeanDefinitionNames();
for(String name:names) {
System.out.println("name="+name);
}*/
app.close();
}
}
运行结果:
这个结果证实了一下问题
1,多实例的时候bean不会随着IOC容器的构建而创建,而是在使用的时候创建的getBean()
2,多实例的时候,当容器进行关闭的时候,bean实例不会调用destroy方法,说明容器不控制多实例的销毁
3,多实例的情况下,返回的bean的对象时不一样的,返回为false
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/111239.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...