Spring Bean的概念

Spring的Bean

Bean是Spring装配的组件模型,一切实体类都可以配置成一个Bean,进而就可以在任何其他的Bean中使用,一个Bean也可以不是指定的实体类,这就是抽象Bean。

在Spring中有两个最基本、最重要的包,即org.springframework.beans和org.springframework.context,在这两个包中,为了实现无侵入式的框架,代码中大量地使用了Java中的反射机制,通过动态调用来避免硬编码,为Spring反向控制提供了基础保证,在这两个包中,最重要的类时BeanFactory和ApplicationContext,BeanFactory提供一种先进的配置机制来管理任何种类的Bean,ApplicationContext是建立在BeanFactory之上的,并增加了其他功能,例如,国际化的支持、资源的访问和事件传播等。

Bean的标识(id和name)

Id属性具有唯一性,每一个Bean只能有一个对应的id,name属性可以指定一个或者多个名称,各个名称之间用逗号或者分号隔开,第一个默认为标识名称,后面的多个自动成为这个Bean的别名。

Bean的class属性

在Spring配置文件中class属性指明Bean的来源,也就是Bean的实际路径,它指向一个实体类。

Bean的作用域

在Spring中可以直接在配置文件中指定类的作用域,scope标识Bean的作用域。

在Spring2.0之前Bean只有两种作用域,即Singleton(单例)和non-Singleton(也称prototype),Spring2.0以后,增加了session、request和global session三个专用于Web应用程序上下文的Bean。

singleton作用域

当一个Bean的作用域设置为Singleton,那么Spring IOC容器中只存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一个实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例。

prototype 

prototype的作用域部署的Bean,每一个请求都会产生一个新的Bean实例,相当于一个new的操作,对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype的整个生命周期复杂,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不负责了。

request

request表示针对每一个HTTP请求都会产生一个新的Bean,同时该Bean仅在当前HTTP Request内有效。

session

session作用域表示针对在一个Http 请求都会产生一个新的Bean,同时该Bean仅在当前Http session范围内有效。

global session

global session 作用域类似于标准的HTTP Session作用域。

Bean的生命周期

一个Bean从建立到销毁,会历经几个执行阶段,如果使用BeanFactory来生成、管理Bean,会尽量支持一下的生命周期。

Bean的建立

由BeanFactory读取Bean的定义文件,并生成各个Bean的实例。

属性注入

执行相关的Bean属性依赖注入

BeanNameAware的setBeanName()

如果Bean类有实现org.springframework.beans.factory.BeanNameAware接口,则执行它的setBeanName()方法。

BeanFactoryAware的setBeanFactory()

如果Bean类实现org.springframework.beans.factory.BeanFactoryAware接口,则执行它的setBeanFactory()方法。

BeanPostProcessors的processBeforeInitialization()

如果有任何的org.springframework.beans.factory.config.BeanPostProcessor实例与Bean实例相关联,则执行BeanPostProcessor实例的processBeforeInitialization()。

InitializingBean的afterPropertiesSet()

如果Bean类有实现org.springframework.beans.factory.InitializingBean,则执行它的afterPropertiesSet()方法。

Bean定义文件中定义init-method

可以在Bean定义文件使用”init-method”属性设置方法名称。

BeanPostProcessors的processAfterInitialization()

如果有任何的org.springframework.beans.factory.config.BeanPostProcessor实例与Bean实例相关联,则执行BeanPostProcessor实例的processAfterInitialization()。

DisposableBean 的destroy()

在容器关闭时,如果Bean类有实现org.springframework.beans.factory.DisposableBean接口,则执行它的destroy()方法。

Bean定义文件中定义destroy –method

在容器关闭时,可以在Bean定义文件使用”destroy –method”属性设置方法名称。

FactoryBean

Spring中有两种类型的Bean,一种是普通的Bean,普通的Bean可以是用户定义的任何类;另一种是工厂Bean,即FactoryBean。工厂Bean与普通的Bean不同,其返回的对象不是指定类的一个实例,其返回的是该工厂Bean的getObject方法返回的对象。在Spring框架内部,AOP相关的功能及事务处理中,很多方法使用到工厂Bean。

BeanPostProcessor

在Bean的依赖关系由Spring容器建立并设置以后,你还有机会定义一些Bean的修正动作来修正相关的属性,方法是让Bean类实现org.springframework.beans.factory.config.BeanPostProcessor接口,该接口与Spring中的定义如下:

public interface BeanPostProcessor { 
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; 
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; 
}

 postProcessBeforeInitialization方法会在Bean类被初始化之前(例如InitializingBean的afterPropertiesSet()方法或者自定义的init方法)被执行,而postProcessAfterInitialization()方法会在Bean类被初始化之后立即被执行。