Spring bean生命周期
bean实例化:创建对象,通过底层的class反射创建。
bean初始化:就是执行那个定义的初始化方法,和java对象的初始化不是一个东西。
1.spring bean的生命周期
-
(实例化前)执行postProcessBeforeInstantiation方法,这里返回的对象会替换掉原来的bean。
-
Bean容器利用java 反射机制实例化Bean,执行clinit,init(构造器)方法。
-
(实例化之后)执行postProcessAfterInstantiation方法,这里如果返回false会跳过依赖注入阶段。
-
执行依赖注入,如@Autowire,@Value,@Resource。
-
Bean容器为实例化的Bean设置属性值;就是下面的这些接口。
-
如果Bean实现了BeanNameAware接口,则执行setBeanName方法;
-
如果Bean实现了BeanClassLoaderAware接口,则执行setBeanClassLoader方法;
-
如果Bean实现了BeanFactoryAware接口,则执行setBeanFactory方法;
-
如果Bean实现了ApplicationContextAware接口,则执行setApplicationContext方法;
-
Aware接口的主要作用是感知,比如有两个bean
<bean id="zhangsan" class="com.github.jettyrun.springinterface.demo.aware.beannameaware.User"> <property name="name" value="zhangsan"></property> <property name="address" value="火星"></property> </bean> <bean id="lisi" class="com.github.jettyrun.springinterface.demo.aware.beannameaware.User2"> <property name="name" value="lisi"></property> <property name="address" value="火星"></property> </bean>
其中user实现了BeanNameAware接口,user2没有,则user可以被注入bean id属性,就是那个zhangsan,而user2就不能获取到lisi。
-
-
(初始化之前)如果加载了BeanPostProcessor相关实现类,则执行postProcessBeforeInitialization方法,这里返回的对象会替换掉原来的bean。
-
如果Bean定义初始化方法(配置init-method、实现了InitializingBean接口),则执行定义的初始化方法;
-
(初始化之后)如果加载了BeanPostProcessor相关实现类,则执行postProcessAfterInitialization方法;
-
当要销毁这个Bean时,如果自定义了销毁方法(PreDestroy注解、配置destroy-method、实现了DisposableBean接口),则执行定义的销毁方法。
@Component
public class LightMgrService {
@Autowired
private LightService lightService;
public LightMgrService() {
lightService.check();
}
}
这样写会导致空指针异常,因为@Autowired
注解的注入是在构造器执行之后的,先初始化bean,再注入属性
3.spring bean的作用域
- Singleton,这是Spring的默认作用域,也就是为每个IOC容器创建唯一的一个Bean实例。
- Prototype,针对每个getBean请求,容器都会单独创建一个Bean实例。
- 如果是web容器,则支持以下三种
- Request,为每个HTTP请求创建单独的Bean实例。
- Session,很显然Bean实例的作用域是Session范围。(另外关于session,浏览器关闭session并不会销毁,可以主动销毁或等待过期,如果sessionid放在会话cookie里,则下次访问会新返回一个sessionid,如果sessionid放在硬盘cookie里,下次访问还是这个sessionid)
- application,应用程序域,应用程序(ServletContext)启动时创建,应用程序关闭时销毁。
4.上面那个问题还可以这样
@Component
public class LightMgrService {
@Autowired
private LightService lightService;
@PostConstruct
public void init() {
lightService.check();
}
}
利用@PostConstruct注解,构造器和Autowired和postconstruct的执行顺序是:Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
5.使用@ Bean 注解的方法所注册的 Bean 对象,如果用户不设置 destroyMethod 属性,此时 Spring 会检查当前 Bean 对象的原始类中是否有名为 shutdown 或者 close 的方法,如果有,此方法会被 Spring 记录下来,并在容器被销毁时自动执行;当然如若没有,那么自然什么都不会发生。而使用@component或@service则不会。