当前位置:   article > 正文

Spring之Spring Bean生命周期_spring bean是由什么容器初始化的?并简述其生命周期。

spring bean是由什么容器初始化的?并简述其生命周期。

1、什么是Bean

2、Spring  Bean  生命周期分为8个步骤

生命周期
什么是生命周期呢?

当前组件在创建到销毁经历的一系列过程,称之为生命周期

生命周期的分为几个阶段?每个阶段有哪些钩子函数?

生命周期分为3个阶段,这三个阶段分别是: 初始化 、 运行中 、 销毁

什么是Bean
首先,我们来看看Spring官方文档对于Bean的定义:

在 Spring 中,构成应用程序主干并由 Spring IoC 容器管理的对象称为 bean。bean 是由 Spring IoC 容器实例化、组装和管理的对象。否则,bean 只是应用程序中的众多对象之一

简单来说bean是计算机自动生成的类,bean是一个由Spring IoC容器实例化、组装和管理的对象。也就是说,bean并不是程序员编辑的,而是程序运行时,由spring通过反射生成的。

首先我们需要知道

在IoC容器启动之后,并不会马上就实例化相应的bean,此时容器仅仅拥有所有对象的BeanDefinition(BeanDefinition:是容器依赖某些工具加载的XML配置信息进行解析和分析,并将分析后的信息编组为相应的BeanDefinition)。只有当getBean()调用时才是有可能触发Bean实例化阶段的活动


为什么说有可能触发Bean实例化阶段?

因为当对应某个bean定义的getBean()方法第一次被调用时,不管是显示的还是隐式的,Bean实例化阶段才会被触发,第二次被调用则会直接返回容器缓存的第一次实例化完的对象实例(因为默认是singleton单例,当然,这里的情况prototype类型的bean除外)

 

Spring Bean的生命周期分为以下八个步骤:

1)通过XML、Java annotation(注解)以及Java Configuration(配置类)等方式加载Spring Bean

2)BeanDefinitionReader:解析Bean的定义。在Spring容器启动过程中,会将Bean解析成Spring内部的BeanDefinition结构;
理解为:将spring.xml中的<bean>标签转换成BeanDefinition结构有点类似于XML解析

BeanDefinition
BeanDefiniton是一个接口,继承自AttributeAccessor和BeanMetadataElement两个接口,这两个接口主要是为了“访问对象相关属性”和“获取元数据相关信息”。BeanDefinition的主要定义对象就是Bean,对bean在整个Spring 容器框架中的基本数据结构进行定义,方便BeanFactory等获取

3)BeanDefinition:包含了很多属性和方法。例如:id、class(类名)、scope、ref(依赖的bean)等等。其实就是将bean(例如<bean>)的定义信息
存储到这个对应BeanDefinition相应的属性中

例如:
<bean id="" class="" scope=""> -----> BeanDefinition(id/class/scope)

4)BeanFactoryPostProcessor:是Spring容器功能的扩展接口。

注意:
4.1)BeanFactoryPostProcessor在spring容器加载完BeanDefinition之后,在bean实例化之前执的4.2)对bean元数据(BeanDefinition)进行加工处理,也就是BeanDefinition属性填充、修改等操作

5)BeanFactory:Bean工厂。它按照我们的要求生产我们需要的各种各样的Bean。

例如:
BeanFactory -> List<BeanDefinition>
BeanDefinition(id/class/scope/init-method)
<bean class="com.zking.spring02.biz.BookBizImpl"/>
foreach(BeanDefinition bean : List<BeanDefinition>){undefined
   根据class属性反射机制实例化对象(CreateBeanInstance方法)
   反射赋值设置属性(PopulateBean方法)
}


6)Aware感知接口:在实际开发中,经常需要用到Spring容器本身的功能资源

例如:BeanNameAware、ApplicationContextAware等等
BeanDefinition 实现了 BeanNameAware、ApplicationContextAware

Spring Aware接口
org.springframework.beans.factory.Aware使得自定义Bean可以识别利用Spring容器的资源,比如:

BeanNameAware.setBeanName(String),可以在Bean中得到它在IOC容器中的Bean的实例的名字
BeanFactoryAware.setBeanFactory(BeanFactory),可以在Bean中得到Bean所在的IOC容器,从而直接在Bean中使用IOC容器的服务
ApplicationContextAware.setApplicationContext(ApplicationContext),可以在Bean中得到Bean所在的应用上下文,从而直接在Bean中使用上下文的服务。
MessageSourceAware,在Bean中可以得到消息源
ApplicationEventPublisherAware,在bean中可以得到应用上下文的事件发布器,从而可以在Bean中发布应用上下文的事件
ResourceLoaderAware,在Bean中可以得到ResourceLoader,从而在bean中使用ResourceLoader加载外部对应的Resource资源
注:Spring官方不推荐自定义Bean实现Aware接口,这会增加代码与Spring 框架的耦合性        

7)BeanPostProcessor:后置处理器。在Bean对象实例化和引入注入完毕后,在显示调用初始化方法的前后添加自定义的逻辑。(类似于AOP的绕环通知)

前提条件:如果检测到Bean对象实现了BeanPostProcessor后置处理器才会执行Before和After方法
BeanPostProcessor
7.1)Before
7.2)调用初始化Bean(InitializingBean和init-method,Bean的初始化才算完成)
7.3)After

完成了Bean的创建工作

8)destory:销毁

SpringBean生命周期中的增强接口PostProcessor

 

总体分为四个阶段:
  BeanDefinitionReader转换Bean结构

  实现BeanFactoryPostProcessor

  1、实例化 CreateBeanInstance
  2、属性赋值 PopulateBean

     实现 Spring   Aware接口
  3、初始化 Initialization
  4、销毁 destory

应用
了解Bean的生命周期有利于我们根据业务需要对Bean进行相关的拓展工作。
举个例子,在Bean初始化前希望用户名和密码。倘若将这些信息硬编码到工厂代码中显然是不安全的,一般地,公司会有一个统一的密码存储服务,通过调用开放的API获取用户名和密码。此时,我们可以在Bean的init-method中加入这样的逻辑:调用公司的密码存储服务API获取用户名和密码,加载至Bean的相关字段中。
再举个例子,在Bean被销毁之前,释放Bean与数据库的连接,那么我们可以把释放数据库连接这段逻辑放到destroy-method中

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/66346
推荐阅读
相关标签
  

闽ICP备14008679号