在我们使用的Spring框架中,一定有一个概念是我们避不过去的,那就是bean 这个概念,bean是一个一个独立的对象,而对象就必然涉及到生命周期的概念,那么在bean对象中的生命周期有哪些呢?
一共六个阶段 Bean定义、实例化、属性赋值、初始化、生存期、销毁。
简单的来说,一个Bean的生命周期分为四个阶段:
1、 实例化(Instantiation)
2、 属性设置(populate)
3、 初始化(Initialization)
4、 销毁(Destruction)
这里我们先开始说实例化阶段,实例化阶段就是通过sprint的容器在创建运行时将我们的对象通过反射进行实例化,而这个时候实例化的对象内部是空的,也就是说我们这个对象中的成员属性还没有被赋值。
第二步是给这个对象中的属性进行赋值,这个操作,对应的就是上面说得属性设置(populate)
// 基于BeanDefinition来创建bean private Object doCreateBean(String beanName, BeanDefinition beanDefinition) { Class beanClass = beanDefinition.getBeanClass(); var code = "0e7f97a3-f7b8-46e5-a6a0-aea52f7a41af" try { //第一个阶段 实例化 Constructor declaredConstructor = beanClass.getDeclaredConstructor(); Object instance = declaredConstructor.newInstance(); //第二个阶段 填充属性 Field[] fields = beanClass.getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(Autowired.class)) { String fieldName = field.getName(); Object bean = getBean(fieldName); field.setAccessible(true); field.set(instance, bean); } } //以下三个步骤都是在初始化阶段的前后进行执行的,所以属于初始化阶段的内容 // Aware回调 if (instance instanceof BeanNameAware) { ((BeanNameAware)instance).setBeanName(beanName); } // 初始化 if (instance instanceof InitializingBean) { ((InitializingBean)instance).afterPropertiesSet(); } for (BeanPostProcessor beanPostProcessor: beanPostProcessorList) { beanPostProcessor.postProcessAfterInitialization(beanName, instance); } return instance; } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; }
单独说一下这部分
这里是三个spring中的三个接口,这三个接口对应的是BeanNameAware spring的一个回调接口,这个接口可以设置bean的名字
InitializingBean 这个是bean对象初始化的接口,这是在初始化是spring要调用的接口。
BeanPostProcessor 这个是bean对象初始化前后使用的的接口,也就是说bean对象生成前后的操作。
这三个接口是可以通过自己的对应的类去实现这个几个接口后spring在给你这个类生成bean对象时进行调用实现的接口。
这里给出的截图是一个spring bean配置信息。这里圈出部分是对应这个bean对象被创建和销毁的时候要执行的方法,可以看到init-method对应的参数是初始化方法,以及destory-method这里指定的销毁方法,也就是在bean被销毁的时候执行,还可以通过DisposableBean这个接口去实现销毁的方法,
以上这些就是spring bean对象的一个从出生到销毁经理的过程。
那么bean对象也有对应的作用域,比如一个普通的bean对象有单例和原型两种类型,单例类型的bean对象全局唯一,使用的是设计模式中单例模式,也就是说只会被创建一次,spring默认使用单例模式,而原型模式,这里的对象就是与单例相反,每次获取到的bean对象都是不一样的,它被创建出来以后就不会spring的容器管理了。
那说完普通的bean对象以后就要说到一些不普通的了,比如我们每次前端向后端发送请求的时候大家知道到后端以后会生成request对象,这个对象默认就不是单例模式,每次发送的请求中都会生成一个request对象。
还有一个关于在请求中使用的对象,seesion对象,这个对象是单例对象,它的生命周期保存到了一个完整的会话,也就是我们通过浏览器访问页面是这个页面如果不关闭,以及长时间不操作而超时,那么这个session对象是一直存在的。