bean 就是由Spring容器 初始化、装配及被管理的对象。
而bean定义 以及bean相互间的依赖 关系 将通过配置元数据 来描述。
在容器内部,bean定义 由BeanDefinition
对象来表示,该定义将包含以下信息:
* 全限定类名: 这通常就是已定义bean的实际实现类。如果通过调用static factory 方法来实例化bean,而不是使用常规的构造器,那么类名称实际上就是工厂类的类名。
* bean行为的定义,即创建模式(prototype还是singleton)、自动装配模式、依赖检查模式、初始化以及销毁方法。这些定义将决定bean在容器中的行为
* 用于创建bean实例的构造器参数及属性值。比如使用bean来定义连接池,可以通过属性或者构造参数指定连接数,以及连接池大小限制等。
* bean之间的关系,即协作 (或者称依赖)。
bean定义 基本上描述了创建一个或多个实际bean对象的内容。当需要的时候,容器会从bean定义列表中取得一个指定的bean定义,并根据bean定义里面的配置元数据使用反射机制来创建一个实际的对象。
org.springframework.beans.factory.BeanFactory
是Spring IoC容器 的实际代表者,职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
BeanFactory
提供的方法极其简单。它仅提供了六种方法供客户代码调用:
* boolean containsBean(String) :如果BeanFactory 包含给定名称的bean定义(或bean实例),则返回true
* Object getBean(String) :返回以给定名字注册的bean实例。根据bean的配置情况,如果为singleton模式将返回一个共享的实例,否则将返回一个新建的实例。如果没有找到指定的bean,该方法可能会抛出BeansException 异常(实际上将抛出NoSuchBeanDefinitionException 异常),在对bean进行实例化和预处理时也可能抛出异常
* Object getBean(String, Class) :返回以给定名称注册的bean实例,并转换为给定class类型的实例,如果转换失败,相应的异常(BeanNotOfRequiredTypeException )将被抛出。上面的getBean(String) 方法也适用该规则。
* Class getType(String name) :返回给定名称的bean的Class 。如果没有找到指定的bean实例,则抛出NoSuchBeanDefinitionException 异常。
* boolean isSingleton(String) :判断给定名称的bean定义(或bean实例)是否为singleton模式,如果bean没找到,则抛出NoSuchBeanDefinitionException 异常。
* String[] getAliases(String) :返回给定bean名称的所有别名。
BeanFactory
对于它所管理的bean提供两种注入依赖方式 (构造器注入和Setter方式注入依赖)。需要注入的依赖将保存在BeanDefinition
中,它能根据指定的PropertyEditor
实现将属性从一种格式转换成另外一种格式。
处理bean依赖关系通常按以下步骤进行:
1. 根据定义bean的配置(文件)创建并初始化BeanFactory 实例(大部份的Spring用户使用支持XML格式配置文件的BeanFactory 或ApplicationContext 实现)。
2. 每个bean的依赖将以属性、构造器参数、或静态工厂方法参数的形式出现。当这些bean被实际创建时 ,这些依赖也将会提供给该bean。(在bean被实际创建 之前,bean的属性并不会被设置。)
3. 每个属性或构造器参数既可以是一个实际的值,也可以是对该容器中另一个bean的引用。
4. 每个指定的属性或构造器参数值必须能够被转换成属性或构造参数所需的类型(PropertyEditor所做的事情 )。默认情况下,Spring会能够以String类型提供值转换成各种内置类型,比如int 、long 、String 、boolean 等。
Bean作用域
作用域 | 描述 |
---|---|
在每个Spring IoC容器中一个bean定义对应一个对象实例。缺省作用域。(经典的GoF Singleton模式中singleton是指在每一个 | |
一个bean定义对应多个对象实例。 | |
在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的Spring | |
在一个HTTP | |
在一个全局的HTTP |
PropertyPlaceholderConfigurer
是个bean工厂后置处理器的实现,可以将BeanFactory
定义中的一些属性值放到另一个单独的标准Java Properties
文件中。这就允许用户在部署应用时只需要在属性文件中对一些关键属性(例如数据库URL,用户名和密码)进行修改,而不用对主XML定义文件或容器所用文件进行复杂和危险的修改。(占位符)
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${ jdbc.driverClassName} "/>
<property name="url" value="${ jdbc.url} "/>
<property name="username" value="${ jdbc.username} "/>
<property name="password" value="${ jdbc.password} "/>
</bean>
context包的核心:ApplicationContext
接口。它由BeanFactory
接口派生而来,因而提供了BeanFactory
所有的功能。为了以一种更向面向框架的方式工作以及对上下文进行分层和实现继承,context包还提供了以下的功能:
* MessageSource , 提供国际化的消息访问
* 资源访问 ,如URL和文件
* 事件传播 ,实现了ApplicationListener 接口的bean
* 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
所有的application context都实现了 ResourceLoader
接口, 可以用它们来获取Resource
实例。
当调用特定application context的 getResource()
方法, 而且资源路径并没有特定的前缀 时,你将获得与该application context相应的 Resource
类型。(UrlResource
,ClassPathResource,
FileSystemResource,
ServletContextResource
)
为了让bean能访问静态资源 ,也可以象其它属性一样注入Resource 。被注入的Resource
属性值可以是简单的路径字符串,ApplicationContext会使用已注册的PropertyEditor
,来将字符串转换为实际的Resource
对象。
Resource strings
前缀 | 例子 | 说明 |
---|---|---|
classpath: |
| 从classpath中加载。 |
file: |
| |
http: |
| 作为 |
(none) |
| 根据 |