Spring基础
Bean的生命周期
参考文档:https://zhuanlan.zhihu.com/p/66719191
要了解bean的生命周期,首先要了解beanDefinition,因为Spring会根据beanDefinition来完成bean的创建,下表为beanDefinition的一部分属性:
属性 | 含义 |
beanClass | Bean类型:UserService.class;orderService.class |
scope | bean的作用域:singleton:单例bean;prototype:原型bean |
lsLazy | 是否需要懒加载 |
dependsOn | bean创建之前所依赖的其他bean |
primary | bean是主bean |
initMethodName | ban的初始化方法 |
- 查找并加载需要被Spring管理的bean,进行Bean的实例化
- 将Bean的引入和值注入到Bean的属性中
- 如果Bean实现了BeanNameAware接口,将Bean的Id传递给setBeanName()方法
- 如果Bean实现了BeanFactoryAware接口,调用setBeanFactory()方法,将BeanFactory容器实例传入
- 如果Bean实现了ApplicationContextAware接口的话,调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。
- 如果Bean实现了BeanPostProcessor接口,调用他们的postProcessBeforeInitialization()方法。
- 如果Bean 实现了InitializingBean接口,调用afterPropertiesSet()方法。如果bean使用init-method声明了初始化方法,该方法也会被调用
- 如果Bean 实现了BeanPostProcessor接口,调用他们的postProcessAfterInitialization()方法。
- 此时,Bean就可以被应用程序使用了。并且一直驻留在应用上下文,直到应用上下文被销毁。
- 如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用。
完整的生命周期:
介绍:
InitializingBean接口作用:此接口只有一个方法:afterPropertiesSet(),如果实现了该方法,Spring容器生产了该接口类的实例后,就会调用afterPropertiesSet方法,这个方法可以检查bean是否正确地被初始化.
如果bean实现了InitializingBean接口,同时配置了init-method,系统则是先调用afterPropertiesSet方法,然后在调用init-method中指定的方法。
Aware
Aware接口:让Bean感知Spring容器的存在,给了程序员可以在bean创建成功后,让spring回调我们业务的接口。
Aware接口 | 说明 | 调用时机 |
ApplicationContextAware | 获取ApplicationContext调用容器的服务 |
ApplicationContextAware.setApplicationContext(): 在普通Bean对象生成之后调用,在InitializingBean.afterPropertiesSet之前调用或者用户自定义初始化方法之前。在ResourceLoaderAware.setResourceLoader,ApplicationEventPublisherAware.setApplicationEventPublisher,MessageSourceAware之后调用。 |
BeanNameAware | 获取当前bean的名称 |
BeanNameAware.setBeanName(): 在普通属性设置之后调用 ,在InitializinngBean.afterPropertiesSet()方法之前调用 |
BeanFactoryAware | 获取BeanFactory调用容器的服务 | BeanFactoryAware.setBeanFactory() : 在普通属性设置之后,,在InitializingBean.afterPropertiesSet()或者自定义初始化方法之前调用 |
ResourceLoaderAware | 将资源或文件(例如文本文件、XML文件、属性文件或图像文件)加载到Spring应用程序上下文中的不同实现 | ResourceLoaderAware.setResourceLoader() : 在普通bean对象之后调用,在afterPropertiesSet 或者自定义的init-method 之前调用,在 ApplicationContextAware 之前调用。 |
ApplicationEventPublisherAware | 应用实践发布器,用来发布事件 | ApplicationEventPublisherAware.setApplicationEventPublisher() : 在普通bean属性之后调用,在初始化调用afterPropertiesSet 或者自定义初始化方法之前调用。 |
EnvironmentAware | 能获取当前容器环境属性信息 |
|
ServletConfigAware | 获取ServletConfig | |
ServletContextAware | 获取ServletContext |
|
MessageSourceAware | 获取国际化文本信息 |
|
BeanClassLoaderAware | 获取加载当前bean的累加载器 |
BeanPostProcessor(bean后置处理器)
Spring 在实例化单例Bean的过程中,会在9个地方执行5个后置处理器。
名称 | 方法 | 说明 |
BeanPostProcessor |
postProcessBeforeInitialization:初始化之前完成一些定制的业务逻辑 postProcessAfterInitialization:初始化完毕时执行的业务逻辑 参数介绍
|
bean工厂的bean属性处理容器,就是可以管理我们的bean工厂内所有的beandefinition(未实例化)数据,可以随心所欲的修改属性。 |
InstantiationAwareBeanPostProcessor |
postProcessBeforeInstantiation(): 在目标对象实例化之前调用,返回值是Object。此时目标对象未被实例化,因此返回值可以代替原本的实例(一般是代理对象)。如果返回值代替原本对象,后续只有postProcessorAfterIniaialization方法会调用,否则按照正常流程走。 postProcessAfterInstantiation(): 方法在目标对象实例化之后调用,此时对象已被实例化,但是实例的属性还未设置。如果返回false,则忽略属性值设置;如果返回true,则正常设置属性值。无论postProcessBeforeInstantiation()返回什么都会执行 postProcessPropertyValues():对属性值进行修改(此时属性值未被设置,可以修改原本该设置进去的属性值),如果postProcessAfterInstantiation()返回false,该方法不会被调用 |
InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口,内部提供了3个方法,再加上BeanPostProcessor接口内部提供的2个方法,所以实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor接口作用:在目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置。 |
SmartInstantiationAwareBeanPostProcessor |
determineCandidateConstructors():监测Bean的构造器 predictBeanType():预测bean的类型 getEarlyBeanReference():循环引用的后置处理器,获取提前暴露的bean引用。用于解决循环引用的问题。只有单例对象才会调用此方法。 |
实例化Bean后置处理器(继承自InstantiationAwareBeanPostProcessor),内部提供了3个方法 |
MergedBeanDefinitionPostProcessor |
postProcessMergedBeanDefinition():缓存bean注入信息的后置处理器,仅缓存(作用:查询),没有完成注入 | 合并bean信息(合并属性)的后置处理器 |
-
实现BeanPostProcessor接口可以对所有bean在创建之前和之后做一些处理
它提供了两个方法:postProcessBeforeInitialization(在bean初始化之前执行), postProcessAfterInitialization(在bean的初始化之后执行)
1、invokeAwareMethods(beanName, bean),对实现了 aware 接口的 bean 进行特殊的处理,可以取得一些相对应的资源。
2、applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName),后置处理器初始化前方法调用。
3、invokeInitMethods(beanName, wrappedBean, mbd),用于初始化方法的调用,如实现了 InitializingBean 接口的 bean ,调用 afterPropertiesSet 或者配置 init-method 方法的调用。