赞
踩
class --> BeanDefinition --> new 对象 (原始对象)--> 属性填充 --> 初始化 --> bean 加入单例池
bean生命周期主要:构造(实例化)-->属性注入(set)-->初始化前-->初始化-->初始化后-->加入单例池待使用-->销毁
Spring bean的生命周期只有四个主要阶段,其他都是在这四个主要阶段前后的扩展点,这四个阶段是:
其中实例化和属性赋值分别对应构造方法和setter方法的注入;初始化和销毁是用户能自定义扩展的两个阶段;属性赋值 Populate,主要是多bean间的依赖属性进行填充。
可通过查源码的方式发现,他们都在doCreateBean()方法中,
- // 忽略了无关代码
- protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
- throws BeanCreationException {
-
- // Instantiate the bean.
- BeanWrapper instanceWrapper = null;
- if (instanceWrapper == null) {
- // 实例化阶段!
- instanceWrapper = createBeanInstance(beanName, mbd, args);
- }
-
- // Initialize the bean instance.
- Object exposedObject = bean;
- try {
- // 属性赋值阶段!
- populateBean(beanName, mbd, instanceWrapper);
- // 初始化阶段!
- exposedObject = initializeBean(beanName, exposedObject, mbd);
- }
-
-
- }
可以发现,分别调用三种方法:
而销毁阶段是在容器关闭时调用的,在ConfigurableApplicationContext类的close()中
两个最重要的接口:
实现这两个接口的bean,会自动切入到相应的生命周期中
具体代码如下:
- package cn.xmx.ioc.lifecycle;
-
- import org.springframework.beans.BeansException;
- import org.springframework.beans.PropertyValues;
- import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
-
- import java.beans.PropertyDescriptor;
-
- public class MyInstantiationAwareBeanPostProcessorAdapter extends InstantiationAwareBeanPostProcessorAdapter {
- @Override
- public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
- if(beanName.equals("car")){
- System.out.println(beanName+"在实例化之前");
- }
-
- return super.postProcessBeforeInstantiation(beanClass, beanName);
- }
-
- @Override
- public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
- if(beanName.equals("car")){
- System.out.println(beanName+"在实例化之后");
- }
- return super.postProcessAfterInstantiation(bean, beanName);
- }
- }
-
- package cn.xmx.ioc.lifecycle;
-
- import java.lang.reflect.Proxy;
-
- import org.springframework.beans.BeansException;
- import org.springframework.beans.factory.config.BeanPostProcessor;
-
-
- //后置处理器
- public class NdBeanPostProcessor implements BeanPostProcessor {
-
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- System.out.println("NdBeanPostProcessor 在"+beanName+"对象初始化之【前】调用......");
- if(beanName.equals("car")) {
- return new CglibInterceptor().getIntance(bean.getClass());
- }
- return bean;
-
- }
-
- public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- System.out.println("NdBeanPostProcessor 在"+beanName+"对象初始化之【后】调用......");
- return bean;
- }
-
- }
-
- package cn.xmx.ioc.lifecycle;
-
- import org.springframework.beans.factory.config.BeanPostProcessor;
- import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- @Configuration
- public class MainConfig {
- @Bean(name="car",initMethod="init",destroyMethod="destroy")
- public Car getCar() {
- return new Car("大黄蜂");
- }
-
- @Bean
- public BeanPostProcessor getBeanPostProcessor() {
- return new NdBeanPostProcessor();
- }
- @Bean
- public InstantiationAwareBeanPostProcessorAdapter getIns(){
- return new MyInstantiationAwareBeanPostProcessorAdapter();
- }
-
- }
-
- package cn.xmx.ioc.lifecycle;
-
- import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
- /*
- 四个主生命周期
- (1)实例化之前干预 InstantiationAwareBeanPostProcessorAdapter.postProcessBeforeInstantiation()
- 1.实例化
- (2)实例化之后干预 InstantiationAwareBeanPostProcessorAdapter.postProcessAfterInstantiation()
- 2.填充属性(给属性赋值)
-
- (1)初始化之前干预 BeanPostProcessor.postProcessBeforeInitialization()
- 3.初始化化(比如准备资源文件)
- 3) 属性进行干预 ----修改属性或属性值
-
- (2)初始化之后干预 BeanPostProcessor.postProcessAfterInitialization()
-
- 4.销毁(释放资源---对象从内存销毁)
- N个接口
- 1、干预多次
- 1)BeanPostProcessor
- 2、干预一次
- 1)Aware
-
- */
- public class TestLifeCycle {
- public static void main(String[] args) {
- AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
- Car car = (Car) context.getBean("car");
- System.out.println(car);//toString
- System.out.println("beanname:"+car.getBeanName());
- System.out.println("beanfactory:"+car.getBeanFactory());
- System.out.println("applicationContext:"+car.getApplicationContext());
- }
- }
需要实体类实现这些接口,分别调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值,调用 setBeanFactory() 方法传入当前工厂实例的引用,调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
具体代码如下图所示:
- package cn.xmx.ioc.lifecycle;
-
- import org.springframework.beans.BeansException;
- import org.springframework.beans.factory.BeanFactory;
- import org.springframework.beans.factory.BeanFactoryAware;
- import org.springframework.beans.factory.BeanNameAware;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.ApplicationContextAware;
-
- public class Car implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {
- private String name;
- private String beanName;
- private BeanFactory beanFactory;
- private ApplicationContext applicationContext;
- public void init() {
- System.out.println("car 在初始化---加载资源");
-
- }
-
- public void destroy() {
- System.out.println("car 在销毁---释放资源");
- }
-
-
-
- public Car() {
- super();
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public Car(String name) {
- super();
- this.name = name;
- System.out.println("car实例化了");
- }
-
-
- public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
- System.out.println("beanFactory:"+beanFactory);
- this.beanFactory = beanFactory;
- }
-
- public BeanFactory getBeanFactory(){
- return this.beanFactory;
- }
-
- public void setBeanName(String s) {
- System.out.println("beanName:"+s);
- this.beanName = s ;
- }
-
- public String getBeanName() {
- return this.beanName;
- }
-
- public ApplicationContext getApplicationContext() {
- return this.applicationContext;
- }
-
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- System.out.println("applicationContext:"+applicationContext);
- this.applicationContext = applicationContext;
- }
- }
-
实例化和属性赋值都是Spring帮助我们做的,能够自己实现的有初始化和销毁两个生命周期阶段。
1.InitializingBean 对应生命周期的初始化阶段,在源码的invokeInitMethods(beanName, wrappedBean, mbd);方法中调用。
2.DisposableBean 类似于InitializingBean,对应生命周期的销毁阶段,以ConfigurableApplicationContext#close()方法作为入口,实现是通过循环取所有实现了DisposableBean接口的Bean然后调用其destroy()方法 。
Bean 生命周期的整个执行过程描述如下:
IOC(控制反转):
控制反转就是本身不负责对象的创建和维护,将管理对象的创建的权利反转给Spring 容器。由Spring 容器进行创建和维护。
DI(依赖注入):
依赖注入由两个或两个以上类体现,会将对象依赖关系自动交给目标对象(DI)管理,无需对象自己获取依赖。
区别:
(1)IoC也称为控制反转,是一种思考方式,其主要关注点在于Java对象的创建与管理的问题。和传统的方式相比,当我们需要一个对象的时候,不需要直接new一个,而是去Spring容器中拿一个即可,此时我们失去了对对象的控制权,仅保有使用权。但这样也可以无需关注对象的管理。
(2)所谓控制,指的是管理对象的权利。
(3)所谓反转,指的是由Spring管理而不是开发者管理。
(4)IoC的其中一个目的是为了解耦合,当将一个对象交给第三方容器管理后,那么对象之间的耦合相较于传统new方式会降低。同时Spring IoC也可以降低对象的管理成本,比如实现单例模式(默认即是单例)等等。
(5)要注意的是,IoC和DI的关系并不是一个,类似于接口和实现类的区别,IoC是一种设计思想,DI是IoC的一种实现,DI也称为依赖注入,在Spring中可以通过@Autowired注解将Spring容器中的对象注入到指定的位置。
【注意】这里罗列了许多知识点总结,并不是要我们去死记硬背,而是在真正理解Spring的底层如何实现后,做一个归纳总结。
●阿里巴巴为什么能抗住90秒100亿?--服务端高并发分布式架构演进之路
●SpringCloud电商秒杀微服务-Redisson分布式锁方案
查看更多好文,进入公众号--撩我--往期精彩
一只 有深度 有灵魂 的公众号0.0
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。