Spring之Bean的生命周期
# spring-bean与普通bean
Spring创建一个Bean不像是传统的javaBean一样,简单的new一个出来,用了等着被回收就完了,Spring对Bean的创建和销毁过程都加入了一些关于Spring本身的操作,比如当Spring容器销毁的时候自动调用Bean的destory方法,如果这个Bean实现了DisposableBean接口的话。
# 图解Spring-Bean的生命周期
# 文解Spring-Bean生命周期
1.Spring对Bean进行实例化 2.将依赖的Bean进行注入,和传入值进行赋值到属性中。 3.如果Bean实现了BeanNameAware接口,Spring将调用setBeanName将Bean的Id传入进来
public class SpringBean implements BeanNameAware {
private String name;
public void setBeanName(String name) {
this.name=name;
//do something
}
}
2
3
4
5
6
7
8
4.如果Bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory将BeanFactory传入进来
public class SpringBean implements BeanFactoryAware {
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
//do something
}
}
2
3
4
5
5.如果Bean实现了ApplicationContextAware接口,那么Spring将会把applicationContext传入调用setApplicationContext方法,这个可以用户获取上下文对象来手动获取Bean
public class SpringBean implements ApplicationContextAware {
public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {
//拿到ApplicationContext对象
}
}
2
3
4
5
6.如果实现了BeanPostProcessor,则调用post-ProcessBeforeInitialization方法。 7.如果Bean实现了InitializingBean,那么则调用after-PropertiesSet 8.如果Bean实现了BeanPostProcessor接口,Spring将调用post-ProcessAfterInitialization方法,这个时候Bean已经加载好了,直到被销毁。 9.如果Bean实现了DisposableBean接口,那么在Bean销毁的时候将会自动调用该Bean的destory方法。
# 一个实用的使用方式
根据以上周期,可以根据其特性来创建一个Spring上下文工具类。使用范围一般在一些静态方法里面使用Spring容器里面的Bean和一些非SpringBean中调用SpringBean对象的时候。SpringContextHolder.getBean(xxx.class) 即可
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
private static ApplicationContext applicationContext = null;
/**
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
assertContextInjected();
return (T) applicationContext.getBean(name);
}
/**
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
public static <T> T getBean(Class<T> requiredType) {
assertContextInjected();
return applicationContext.getBean(requiredType);
}
/**
* 检查ApplicationContext不为空.
*/
private static void assertContextInjected() {
if (applicationContext == null) {
throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext" +
".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder.");
}
}
/**
* 清除SpringContextHolder中的ApplicationContext为Null.
*/
private static void clearHolder() {
log.debug("清除SpringContextHolder中的ApplicationContext:"
+ applicationContext);
applicationContext = null;
}
@Override
public void destroy(){
SpringContextHolder.clearHolder();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringContextHolder.applicationContext != null) {
log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);
}
SpringContextHolder.applicationContext = applicationContext;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53