Spring Bean

什么是Bean?

  Spring 的三大核心组件:Core ,Context,Beans,构建起了Spring的骨骼架构,没有他们就不可能有AOP,Web 等上层功能特性。其中最核心的是Beans组件,为什么呢,其实Spring 就是面向Bean编程(BOP) 。为什么Bean在Spring中如此重要?因为Spring建立之初就是为了解决对象之间的依赖关系。它把对象之间的依赖关系通过配置文件来管理,也就是依赖注入机制。而这个注入关系在一个叫IOC的容器中管理,IOC容器中就有了Bean包裹的对象。Spring正是通过把对象包装在Bean中从而达到对这些对象管理以及一些额外操作。

JavaBean 和Spring的Bean有什么区别?

  用处不同:传统javabean更多地作为值传递参数,而spring中的bean用处几乎无处不在,任何组件都可以被称为bean。

  写法不同:传统javabean作为值对象,要求每个属性都提供getter和setter方法;但spring中的bean只需为接受设值注入的属性提供setter方法。

  生命周期不同:传统javabean作为值对象传递,不接受任何容器管理其生命周期;spring中的bean有spring管理其生命周期行为。

  所有可以被spring容器实例化并管理的java类都可以称为bean。


 

Spring Bean 的生命周期

  Spring框架中,一旦把一个Bean纳入Spring IOC容器之中,这个Bean的生命周期就会交由容器进行管理,一般担当管理角色的是BeanFactory或者ApplicationContext,认识一下Bean的生命周期活动,对更好的利用它有很大的帮助。
   
   对于ApplicationContext容器,当容器启动结束后,便实例化所有的bean。对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。
  容器通过获取BeanDefinition对象中的信息进行实例化。并且这一步仅仅是简单的实例化,并未进行依赖注入。
  实例化对象被包装在BeanWrapper对象中,BeanWrapper提供了设置对象属性的接口,并且此时对象仍然是一个原生的状态,并没有进行依赖注入。
  紧接着,Spring根据BeanDefinition中的信息进行依赖注入。
  接着,Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给bean。
  当经过上述几个步骤后,bean对象已经被正确构造,但如果你想要对象被使用前再进行一些自定义的处理,就可以通过BeanPostProcessor接口实现
  InitializingBean 与 init-method
  DisposableBean 与 destroy-method 

第二种解释:

  1. 实例化一个bean,也就是我们通常说的new
  2. 按照spring上下文对实例化的bean进行配置,也就是依赖注入
  3. 如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的是Spring配置文件中Bean的ID
  4. 如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(),传递的是Spring工厂本身(可以用这个方法获取到其他Bean)
  5.  如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文,该方式同样可以实现步骤4,但比4更好,以为ApplicationContext是BeanFactory的子接口,有更多的实现方法
  6. 如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用After方法,也可用于内存或缓存技术
  7. 如果这个Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法
  8. 如果这个Bean关联了BeanPostProcessor接口,将会调用postAfterInitialization(Object obj, String s)方法

注意:以上工作完成以后就可以用这个Bean了,那这个Bean是一个single的,所以一般情况下我们调用同一个ID的Bean会是在内容地址相同的实例

  • 当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean接口,会调用其实现的destroy方法
  • 最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法

以上10步骤可以作为面试或者笔试的模板,另外我们这里描述的是应用Spring上下文Bean的生命周期,如果应用Spring的工厂也就是BeanFactory的话去掉第5步就Ok了

 

 


 

 

分析

Bean 组件在 Spring 的 org.springframework.beans 包下。这个包下的所有类主要解决了三件事:Bean 的定义、Bean 的创建以及对 Bean 的解析。

Bean的创建:BeanFactory 有三个子类:ListableBeanFactory、HierarchicalBeanFactory 和 AutowireCapableBeanFactory。但是从上图中我们可以发现最终的默认实现类是 DefaultListableBeanFactory,他实现了所有的接口。 
  那为何要定义这么多层次的接口呢?因为每个接口都有他使用的场合,它主要是为了区分在 Spring 内部在操作过程中对象的传递和对象的数据访问限制。例如 ListableBeanFactory 接口表示这些 Bean 是可列表的,而 HierarchicalBeanFactory 表示的是这些 Bean 是有继承关系的,也就是每个 Bean 有可能有父 Bean。AutowireCapableBeanFactory 接口定义 Bean 的自动装配规则。这四个接口共同定义了 Bean 的集合、Bean 之间的关系、以及 Bean 行为。

Bean 的定义:Bean 的定义主要是 BeanDefinition ,就是完整的描述了在 Spring 的配置文件中我们定义的 节点中所有的信息,包括各种子节点。当 Spring 成功解析定义的一个 节点后,在 Spring 的内部他就被转化成 BeanDefinition 对象。以后所有的操作都是对这个对象完成的。

Bean 的解析:过程非常复杂,功能被分的很细,因为这里需要被扩展的地方很多,必须保证有足够的灵活性,以应对可能的变化。Bean 的解析主要就是对 Spring 配置文件的解析。

 

posted @ 2018-04-14 16:44  污力豆豆  阅读(214)  评论(0编辑  收藏  举报