Spring注解开发
今天,学习Bean的生命周期
Bean的生命周期
在Spring中Bean的生命周期:
Bean的创建—-初始化—–调用—–销毁。
构造(对象的创建):
单实例:在容器启动的时候创建对象
多实例:在每次获取的时候创建对象
初始化:
对象创建完成,并赋值好,调用初始化方法
销毁:
单实例:容器关闭的时候
多实例:容器不会管理这个Bean,容器不会调用销毁方法
以前,我们定义初始化和销毁方法是在xml文件中配置的:
<!--以前的开发模式,使用配置文件-->
<bean id="person" class="com.liuzhuo.bean.Person" init-method="" destroy-method="">
<property name="name" value="zhangsan"/>
<property name="age" value="18"/>
</bean>
init-method=”” : 定义初始化方法
destroy-method=”” : 定义销毁方法
现在,我们可以使用其他方式来完成生命周期。
通过@Bean指定init-method和destroy-method
1)在com.liuzhuo.config包下,创建MainConfigOfLife配置类:
@Configuration
public class MainConfigOfLife {
}
2) 在com.liuzhuo.bean包下,创建Car类:
public class Car {
public Car() {
System.out.println("Car construct ····");
}
//定义初始化方法
public void init(){
System.out.println("Car init ·····");
}
//定义销毁方法
public void destory(){
System.out.println("Car destory ·····");
}
}
3) 将Car注册到容器中:
@Configuration
public class MainConfigOfLife {
@Bean(initMethod = "init",destroyMethod = "destory")
public Car car() {
return new Car();
}
}
4) 在com.liuzhuo.test包下,创建新的测试类(IocOfLifeTest):
public class IocOfLifeTest {
@Test
public void test01() {
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MainConfigOfLife.class);
}
}
5)运行测试test01方法:
Car construct ····
Car init ·····
说明:单例模式下,容器启动就会将Bean对象注入到容器中,并执行了初始化方法。
想要调用销毁方法,关闭容器就好。
public class IocOfLifeTest {
@Test
public void test01() {
//启动容器
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MainConfigOfLife.class);
//关闭容器
applicationContext.close();
}
}
运行结果:
D:\Java1.8\bin\java
十月 15, 2018 9:08:11 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2f410acf: startup date [Mon Oct 15 21:08:11 CST 2018]; root of context hierarchy
Car construct ····
Car init ·····
十月 15, 2018 9:08:11 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2f410acf: startup date [Mon Oct 15 21:08:11 CST 2018]; root of context hierarchy
Car destory ·····
Process finished with exit code 0
InitializingBean和DisposableBean
通过让Bean实现InitializingBean和DisposableBean两个接口来定义初始化和销毁。
1)在com.liuzhuo.bean包下,创建Cat类,并实现上述两个接口:
@Component
public class Cat implements InitializingBean, DisposableBean {
public Cat() {
System.out.println("Cat constructer ···");
}
@Override
public void destroy() throws Exception {
System.out.println("Cat destroy ····");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Cat afterPropertiesSet ····");
}
}
2) 将Cat类注入到容器中,这里我使用了包扫描:
@Configuration
@ComponentScan(value = "com.liuzhuo")
public class MainConfigOfLife
3) 运行测试方法test01:
public class IocOfLifeTest {
@Test
public void test01() {
//启动容器
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MainConfigOfLife.class);
Object cat = applicationContext.getBean("cat");
//关闭容器
applicationContext.close();
}
}
4) 结果:
十月 15, 2018 9:21:42 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory registerBeanDefinition
信息: Overriding bean definition for bean 'person' with a different definition: replacing [Generic bean: class [com.liuzhuo.bean.Person]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [E:\ideaProject\springannotation\target\classes\com\liuzhuo\bean\Person.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=true; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=mainConfig2; factoryMethodName=person; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/liuzhuo/config/MainConfig2.class]]
Cat constructer ···
Cat afterPropertiesSet ····
Car construct ····
Car init ·····
十月 15, 2018 9:21:43 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2f410acf: startup date [Mon Oct 15 21:21:42 CST 2018]; root of context hierarchy
Car destory ·····
Cat destroy ····
JSR250:@PostConstruct和@PreDestory
@PostConstruct: 在bean创建完成并且属性赋值完成,来执行初始化方法
@PreDestory: 在容器销毁bean之前通知我们进行清理工作
1) 在com.liuzhuo.bean包下,创建Dog类:
@Component
public class Dog {
public Dog() {
System.out.println("Dog construct ····");
}
//在构造函数之后
@PostConstruct
public void init() {
System.out.println("Dog @PostConstruct ····");
}
//在销毁之前
@PreDestroy
public void destory() {
System.out.println("Dog @PreDestroy ····");
}
}
2) 运行测试类test01:
public class IocOfLifeTest {
@Test
public void test01() {
//启动容器
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MainConfigOfLife.class);
applicationContext.getBean("dog");
//关闭容器
applicationContext.close();
}
}
3) 结果:
十月 15, 2018 9:35:11 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory registerBeanDefinition
信息: Overriding bean definition for bean 'person' with a different definition: replacing [Generic bean: class [com.liuzhuo.bean.Person]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [E:\ideaProject\springannotation\target\classes\com\liuzhuo\bean\Person.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=true; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=mainConfig2; factoryMethodName=person; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/liuzhuo/config/MainConfig2.class]]
Cat constructer ···
Cat afterPropertiesSet ····
Dog construct ····
Dog @PostConstruct ····
Car construct ····
Car init ·····
十月 15, 2018 9:35:12 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2f410acf: startup date [Mon Oct 15 21:35:11 CST 2018]; root of context hierarchy
Car destory ·····
Dog @PreDestroy ····
Cat destroy ····
BeanPostProcessor
BeanPostProcessor: bean后置处理器(意思是bean初始化前后执行)
postProcessBeforeInitialization:在初始化之前执行,这里是初始化指:上述的init-method、InitializingBean、@PostConstruct。
postProcessAfterInitialization:在初始化之后执行。
1)在com.liuzhuo.bean包下,创建MyBeanPostProcessor并实现BeanPostProcessor接口
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
//初始化之前执行
/**
* @param bean 容器创建的Bean
* @param beanName bean的id
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "------postProcessBeforeInitialization");
//返回值是原始的Bean,或者是包装后的Bean
return bean;
}
//初始化之后执行
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "------postProcessAfterInitialization");
return bean;
}
}
3) 运行测试方法test01:
public class IocOfLifeTest {
@Test
public void test01() {
//启动容器
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MainConfigOfLife.class);
applicationContext.getBean("dog");
//关闭容器
applicationContext.close();
}
}
4) 结果:
mainConfigOfLife------postProcessBeforeInitialization
mainConfigOfLife------postProcessAfterInitialization
Cat constructer ···
cat------postProcessBeforeInitialization
Cat afterPropertiesSet ····
cat------postProcessAfterInitialization
Dog construct ····
dog------postProcessBeforeInitialization
Dog @PostConstruct ····
dog------postProcessAfterInitialization
Car construct ····
car------postProcessBeforeInitialization
Car init ·····
car------postProcessAfterInitialization
Car destory ·····
Dog @PreDestroy ····
Cat destroy ····
十月 15, 2018 9:57:03 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2f410acf: startup date [Mon Oct 15 21:57:03 CST 2018]; root of context hierarchy
Process finished with exit code 0
分析:
Cat constructer ···
cat——postProcessBeforeInitialization
Cat afterPropertiesSet ····
cat——postProcessAfterInitialization
Cat destroy ····
构造–初始化之前–初始化–初始化之后–销毁