【Spring IoC】Spring Bean(三)
一、Spring Bean的定义
被称作 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的。bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。这些 bean 是由容器提供的配置元数据创建的。
bean 定义包含称为配置元数据的信息。主要包括:
- 如何创建一个 bean
- bean 的生命周期的详细信息
- bean 的依赖关系
每个 bean 可以定义的属性有:
- class:必填,用来定义类的全限定名(包名+类名)。只有子类Bean不用定义该属性。
- id:Bean的唯一标识名。它必须是合法的XML ID,在整个XML文档中唯一。
- name:用来为id创建一个或多个别名。它可以是任意的字母符合。多个别名之间用逗号或空格分开。你可以使用 ID 和/或 name 属性来指定 bean 标识符。
- parent:子类Bean定义它所引用它的父类Bean。这时前面的class属性失效。子类Bean会继承父类Bean的所有属性,子类Bean也可以覆盖父类Bean的属性。注意:子类Bean和父类Bean是同一个Java类。
- abstract(默认为”false”):用来定义Bean是否为抽象Bean。它表示这个Bean将不会被实例化,一般用于父类Bean,因为父类Bean主要是供子类Bean继承使用。
- singleton(默认为“true”):定义Bean是否是Singleton(单例)。如果设为“true”,则在BeanFactory作用范围内,只维护此Bean的一个实例。如果设为“flase”,Bean将是Prototype(原型)状态,BeanFactory将为每次Bean请求创建一个新的Bean实例。
- lazy-init(默认为“default”):用来定义这个Bean是否实现懒初始化。如果为“true”,它将在BeanFactory启动时初始化所有的Singleton Bean。反之,如果为“false”,它只在Bean请求时才开始创建Singleton Bean。lazy-init 设置只对scop属性为singleton的bean起作用。
- autowire(自动装配,默认为“default”):它定义了Bean的自动装载方式。
- “no”:不使用自动装配功能。
- “byName”:通过Bean的属性名实现自动装配。
- “byType”:通过Bean的类型实现自动装配。
- “constructor”:类似于byType,但它是用于构造函数的参数的自动组装。
- “autodetect”:通过Bean类的反省机制(introspection)决定是使用“constructor”还是使用“byType”。
- dependency-check(依赖检查,默认为“default”):它用来确保Bean组件通过JavaBean描述的所以依赖关系都得到满足。在与自动装配功能一起使用时,它特别有用。depends-on(依赖对象):这个Bean在初始化时依赖的对象,这个对象会在这个Bean初始化之前创建。
- none:不进行依赖检查。
- objects:只做对象间依赖的检查。
- simple:只做原始类型和String类型依赖的检查
- all:对所有类型的依赖进行检查。它包括了前面的objects和simple。
- init-method:用来定义Bean的初始化方法,它会在Bean组装之后调用。它必须是一个无参数的方法。
- destroy-method:用来定义Bean的销毁方法,它在BeanFactory关闭时调用。同样,它也必须是一个无参数的方法。它只能应用于singleton Bean。constructor-arg:用来注入依赖关系的
- factory-method:定义创建该Bean对象的工厂方法。它用于下面的“factory-bean”,表示这个Bean是通过工厂方法创建。此时,“class”属性失效。
- factory-bean:定义创建该Bean对象的工厂类。如果使用了“factory-bean”则“class”属性失效。
- scope:指定由特定的 bean 定义创建的对象的作用域,可以有singleton、prototype、request、session和global session
二、Spring Bean的作用域
当在 Spring 中定义一个 bean 时,你必须声明该 bean 的作用域的选项。例如,为了强制 Spring 在每次需要时都产生一个新的 bean 实例,你应该声明 bean 的作用域的属性为 prototype。同理,如果你想让 Spring 在每次需要时都返回同一个bean实例,你应该声明 bean 的作用域的属性为 singleton。
Spring 框架支持以下五个作用域,分别为singleton、prototype、request、session和global session。
1. singleton
singleton 是默认的作用域,也就是说,当定义 bean 时,如果没有指定作用域配置项,则 bean 的作用域被默认为 singleton。
当一个bean的作用域为Singleton,那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。
singleton是单例类型,就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。注意,singleton作用域是Spring中的缺省作用域。你可以在 bean 的配置文件中设置作用域的属性为 singleton。
2. prototype
当一个bean的作用域为prototype,表示一个bean定义对应多个对象实例。
prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例
prototype是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。
3. request
每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境。
4. session
同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境
5. global-session
一般用于Portlet应用环境,该运用域仅适用于WebApplicationContext环境。
三、Spring Bean的生命周期
1. spring bean的生命周期图
- spring对bean进行实例化,默认bean是单例
- spring对bean进行依赖注入
- 如果bean实现了BeanNameAware接口,spring将bean的id传给setBeanName()方法
- 如果bean实现了BeanFactoryAware接口,spring将调用setBeanFactory方法,将BeanFactory实例传进来
- 如果bean实现了ApplicationContextAware()接口,spring将调用setApplicationContext()方法将应用上下文的引用传入
- 如果bean实现了BeanPostProcessor接口,spring将调用它们的postProcessBeforeInitialization接口方法
- 如果bean实现了InitializingBean接口,spring将调用它们的afterPropertiesSet接口方法,类似的如果bean使用了init-method属性声明了初始化方法,改方法也会被调用
- 如果bean实现了BeanPostProcessor接口,spring将调用它们的postProcessAfterInitialization接口方法
- 此时bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中,直到该应用上下文被销毁
- 若bean实现了DisposableBean接口,spring将调用它的distroy()接口方法。同样的,如果bean使用了destroy-method属性声明了销毁方法,则该方法被调用
2. 各种接口方法分类
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
(1) 容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”;AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer就是非常有用的工厂后处理器;
(2) Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法;
(3) Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法;
3. BeanFactoryPostProcessor 和 BeanPostProcessor
Spring中BeanFactoryPostProcessor和BeanPostProcessor都是Spring初始化bean时对外暴露的扩展点。
(1) BeanFactoryPostProcessor
Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。同时可以定义多个BeanFactoryPostProcessor,通过设置'order'属性来确定各个BeanFactoryPostProcessor执行顺序。
注册一个BeanFactoryPostProcessor实例需要定义一个Java类来实现BeanFactoryPostProcessor接口,并重写该接口的postProcessorBeanFactory方法。通过beanFactory可以获取bean的定义信息,并可以修改bean的定义信息。
在Spring中内置了一些BeanFactoryPostProcessor实现类:
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
org.springframework.beans.factory.config.PropertyOverrideConfigurer
org.springframework.beans.factory.config.CustomEditorConfigurer:用来注册自定义的属性编辑器
(2) BeanPostProcessor
如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中。
- 后置处理器的postProcessorBeforeInitailization方法是在bean实例化,依赖注入之后及自定义初始化方法(例如:配置文件中bean标签添加init-method属性指定Java类中初始化方法、@PostConstruct注解指定初始化方法,Java类实现InitailztingBean接口)之前调用;
- 后置处理器的postProcessorAfterInitailization方法是在bean实例化、依赖注入及自定义初始化方法之后调用。
注意:
接口中两个方法不能返回null,如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象 ,因为后置处理器从Spring IoC容器中取出bean实例对象没有再次放回IoC容器中。
BeanFactory和ApplicationContext两个容器对待bean的后置处理器稍微有些不同。ApplicationContext容器会自动检测Spring配置文件中那些bean所对应的Java类实现了BeanPostProcessor接口,并自动把它们注册为后置处理器。在创建bean过程中调用它们,所以部署一个后置处理器跟普通的bean没有什么太大区别。
BeanFactory容器注册bean后置处理器时必须通过代码显示的注册,在IoC容器继承体系中的ConfigurableBeanFactory接口中定义了注册方法:void addBeanPostProcessor(BeanPostProcessor beanPostProcessor)
Spring调用多个BeanPostProcessor实现类时,默认是根据后置处理器的定义顺序来依次调用。当然,也可以让BeanPostProcessor接口实现类实现Ordered接口getOrder方法,该方法返回一整数,默认值为 0,优先级最高,值越大优先级越低。
四、Spring Bean的继承
在基于XML配置元数据中,bean标签可以包含很多配置信息,可以包含构造函数的参数,属性值以及其他一些初始化方法。子bean的定义可以继承父bean定义元数据,子bean定义可以根据需要重写父bean属性值或者添加一些其他属性。
Spring bean中的继承和Java中继承无关,只是继承的思想一致。可以把父bean作为一个定义模板,供其他子bean使用。
【Spring IoC】Spring Bean(三)的更多相关文章
- 使用Spring IoC进行Bean装配
Spring概述 Spring的设计严格遵从的OCP(开闭原则),保证对修改的关闭,也就是外部无法改变spring内部的运行流程:提供灵活的扩展接口,也就是可以通过extends,implements ...
- Spring IOC 之Bean作用域
当你创建一个bean定义的时候,你创建了一份通过那种bean定义的bean的创建类的真正实力的处方.bean的定义是一个处方 的想法是很重要的的.因为这意味着,对于一个类你可以创建很多对象实例从一个单 ...
- Spring IOC之Bean 概述
1.Bean概述 一个Spring IOC容器管理一个或者多个bean.这些bean是根据你提供给容器的配置数据信息创建的,例如XML形式的的定义. 在容器内部,这些bean的定义表示为BeanDef ...
- Spring IOC的Bean对象
---恢复内容开始--- 在Spring IOC模块中Bean是非常重要的.在这里我想给大家讲讲关于Bean对象实例化的三种注入方式: 首先,我先讲一下关于Bean对象属性值的两种注入方式:set注入 ...
- spring IOC装配Bean(注解方式)
1 Spring的注解装配Bean (1) Spring2.5 引入使用注解去定义Bean @Component 描述Spring框架中Bean (2) Spring的框架中提供了与@Componen ...
- Spring——IOC与Bean容器
[IOC] (1)IOC:控制反转,控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是由外部容器负责创建和维护.也就是说由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中 (2)DI: ...
- Spring IOC 之Bean定义的继承
一个Bean的定义可以包含大量的配置信息,包括构造器参数.属性值以及容器规范信息,比如初始化方法.静态工厂方法名字等等.一子bean的定义可以从父bean的定义中继承配置数据信息.子bean定义可以覆 ...
- Spring - IoC(3): Bean 实例的创建方式
创建一个 Bean 实例对象的方法通常有如下方式: 调用构造器创建 Bean 实例 调用静态工厂方法创建 Bean 实例 调用实例工厂方法创建 Bean 实例 使用构造器创建 Bean 实例 XML ...
- Spring IoC源码解析——Bean的创建和初始化
Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...
- Spring IoC Container and Spring Bean Example Tutorial
Spring Framework is built on the Inversion of Control (IOC) principle. Dependency injection is the t ...
随机推荐
- sqlserver deadlock
当时系统测试的时候,由于使用了自动化测试跑脚本,一下子出了很多sqlserver deadlock的问题. 都处于system test阶段了,哪儿还有时间仔细分析这些死锁是怎么出来的,直接上retr ...
- .Net Framework与.Net Core文件系统的差异
在.Net Fx下,可通过try/catch实例化DirectoryInfo/FileInfo来判断用户输入的路径是否合法,但我把代码拷到 .Net Core 下运行,发现运行结果完全不同 var d ...
- (二十)golang--变量的作用域
(1)函数内部申明/定义的变量叫局部变量,作用域仅限于函数的内部: (2)函数外部申明/定义的变量叫全局变量,作用域在整个包都有效,如果其首字母为大写,则作用域是整个程序: (3)如果变量是在一个代码 ...
- H3C 12508 收集诊断信息
案例:H3C 12508单板卡出现remove状态,需要配合研发收集诊断信息. (此文档只展示研发要求的诊断信息.) 总体:12500交换机返回三种文件----故障时诊断信息,主备单板的日志文 ...
- python asyncio 关闭task
import asyncio import time async def get_html(sleep_times): print("waiting") await asyncio ...
- java函数式编程的形式
java中没有真正的函数变量: 一.所有的函数(拉姆达)表达式,都被解释为functional interface @FunctionalInterface interface GreetingSer ...
- Kafka学习笔记之Kafka High Availability(上)
0x00 摘要 Kafka在0.8以前的版本中,并不提供High Availablity机制,一旦一个或多个Broker宕机,则宕机期间其上所有Partition都无法继续提供服务.若该Broker永 ...
- Microsoft.Windows.Controls.Ribbon.RibbonWindow 碰到 AvalonDock出现的诡异现象
部分一 14年底进入目前公司时,领导准备开发一款新软件平台以取代原有平台.原平台采用C++Build开发界面(window c/s客户端) .Visual Studio(封装dll模块).过完年,领导 ...
- c++实现文件复制并修改相应属性
问题描述 完成一个目录复制命令mycp,包括目录下的文件和子目录, 运行结果如下: beta@bugs.com [~/]# ls –la sem total 56 drwxr-xr-x 3 beta ...
- Java生鲜电商平台-积分,优惠券,会员折扣,签到、预售、拼团、砍价、秒杀及抽奖等促销模块架构设计
Java生鲜电商平台-积分,优惠券,会员折扣,签到.预售.拼团.砍价.秒杀及抽奖等促销模块架构设计 说明:本标题列举了所有目前社会上常见的促销方案,目前贴出实际的业务运营手段以及架构设计,包括业务说明 ...