spring framework

1. The IoC container

1.1.Spring IoC container and beans 介绍

本章主要内容是 Spring Framework 控制反转 (IoC) 技术的实现原理. 控制反转(IoC)也叫依赖注入(DI).控制反转是这样一个过程: objects 只能通过 构造函数参数、工厂方法参数、或者在由构造函数或者工厂方法返回的object 实例 上设置的属性 这些方式定义它们的依赖。spring容器在生产这些bean的时候就会注入这些依赖。

之前都是bean 使用依赖类的构造函数自己来控制依赖的实例化,现在这个过程从根本上反转了, 因此叫控制反转 (IoC)。

org.springframework.beans 和 org.springframework.context 两个包是IoC 容器的基础. BeanFactory 接口 提供了能够管理任何类型的对象的高级配置机制。 ApplicationContext 是 BeanFactory 的一个子接口. 它可以更容易地集成Spring’s AOP 、增加了 信息资源处理 (国际化), 事件发布、 以及应用层专门的 contexts 例如 web 应用中的 WebApplicationContext .

简言之,BeanFactory 提供了framework的配置和基础功能,并且 ApplicationContext 添加了企业级的功能。ApplicationContext 是 BeanFactory 的超集,广泛地在 Spring's Ioc 容器中使用。

 在Spring中, objects 是 application的骨架,这些objects由 Spring Ioc container 管理,也叫 beans. 一个 bean 就是 object。它的实例化、装配都是由Spring Ioc container 管理。Beans 以及它们的依赖关系都保存在于容器的配置元数据中。

1.2. Container overview

org.springframework.context.ApplicationContext 接口代表了 Spring IoC container 并且负责实例化、配置和装配上述的 beans. The container 从配置元数据中得到beans的构造函数. 配置元数据可以呈现为  XML, 注解(Java annotations), 或 Java code. 这些元数据解释了 objects 和它们之间的依赖关系。

在一个独立的应用中,通常是用创建一个 ClassPathXmlApplicationContext 实例或者 FileSystemXmlApplicationContext实例。XML 是定义配置元数据的传统格式,你也可以使用java annotations或者code作为元数据格式。

在许多应用场景里,实例化一个或多个spring Ioc container 是不需要用户代码的。比如在一个web application中,一个简单的几行的 web.xml配置文件就可以实现了。

下面这个图表是一个高级别的视图,说明了 Spring 是如何工作的。 你应用中的 classes 是和 配置元数据绑定在一起的,所以在 ApplicationContext 创建完成后,你就有了一个完整的配置和可执行的系统或应用。


1.2.1. Configuration metadata

图表中已经展示了, the Spring IoC container 吃掉了(消费了)  配置元数据; 这些配置元数据代表了你作为开发者如何告诉 Spring container 实例化、配置和装配应用中的 objects. 配置元数据通常是 XML 格式. XML格式不是配置元数据的唯一方式. The Spring IoC container 本身和这些配置元数据是完全分开的. 现如今开发者们更多选择基于java 的配置.基于java的配置始于 Spring 3.0, Spring JavaConfig project 提供的特性成为了 Spring Framework 内核的一部分. 这样你就可以用java代码而不是xml文件在外层定义beans。要使用这些新特性,可以参考 @Configuration, @Bean, @Import and @DependsOn annotations.  Java configuration 通常在@Configuration 注解的类中用 @Bean 注解的方法来实现bean的定义。通常你会定义service层的objects,数据访问层的objects(DAOs),表现层的objects比如 strtus action 实例和infrastructure objects比如 Hibernate SessionFactories、JMS Queues等。通常情况下容器中是不配置详细的域对象(实体类对象)的,因为这是dao层和业务层负责的,由它们去创建和加载域对象(实体类对象). 然而,spring 可以集成 AspectJ 来配置那些不是由Ioc 容器控制的外部对象。参考Spring AspectJ 依赖注入域对象。

基于xml格式的元数据配置例子:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="..." class="..."><property name="" ref=""/></bean>

<bean id="..." class="..."></bean>

</beans>

id 属性是bean 的唯一标识, class属性表示bean的类型,要用类的全路径为class赋值。property 标签来配置这个bean的依赖。

1.2.2. Instantiating a container

实例化Spring Ioc 容器是很直接的。 提供给 ApplicationContext 构造函数的一个或多个resource路径字符串能够允许容器将配置元数据加载进来。这些资源可以是本地的文件系统,也可以是java的CLASSPATH等等。

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

学习完 Spring's Ioc 容器后,你就会想知道更多关于 Spring's Resource abstraction的内容,它提供了一个非常好的机制来读取流文件。特别地,资源的路径常用于applications contexts 的构造过程。

如下示例了服务层对象的配置文件:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">

<property name="accountDao" ref="accountDao"/>

<property name="itemDao" ref="itemDao"/>

</bean>

</beans>

如下示例了数据层对象的配置文件:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="accountDao"

class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">

<!-- additional collaborators and configuration for this bean go here --></bean>

<bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao"></bean>

</beans>

这个例子中,服务层由 PetStoreServiceImpl 类和两个数据访问层对象 JpaAccountDao 和 JpaItemDao. property 标签name 属性是javabean 属性的名字,ref属性是所引用的javabean. 通过id 和ref 表达式构建起bean之间的依赖关系。

创建基于xml的配置元数据

通常情况下每个逻辑层或模块由单独的 xml配置文件来定义。

你可以用 application context 构造器把这些 xml fragments 加载进来。构造器可以有多个路径参数来加载多个配置文件。另外,也可以在一个xml配置文件中用import 标签引用 其它的xml配置文件:

<beans>

<import resource="services.xml"/>

<import resource="resources/messageSource.xml"/>

<bean id="bean1" class="..."/>

<bean id="bean2" class="..."/>

</beans>

1.2.3. Using the container

ApplicationContext 是一个接口, 实现这个接口的类就相当于一个高级工厂类,它可以获取所有beans的注册信息和依赖信息。 使用 T getBean 方法可以获取到bean 的实例。

 ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

 PetStoreService service = context.getBean("petStore", PetStoreService.class);

 List<String> List = service.getUsernameList();

Spring Ioc 容器管理一个或多个bean. 这些beans 是容器根据你提供的配置元数据来创建的。在容器内部,这些bean的定义信息包括:

1)一个带有包限定的类名,通常是一个实现类。

2)bean的行为配置元素,定义了这个bean将如何表现,比如它的作用域,生命周期回调函数等

3)这个bean所依赖的其它bean

4)新建的bean上的其它设置,比如这个bean使用的连接数,连接池的连接数限制等信息。

1.3.1. Naming beans

每个bean可以有一个或多个标识符,你可以用 id或name属性来指定bean的标识符。 id 属性只允许你指定 一个id值。 约定中,name属性可以由文字数字组成,但是也可以包含一些特殊字符。如果你想给这个bean

其它的别名,你可以在name属性里添加它们,用豆号,分号或空格隔开。

为bean提供id 或name不是必须的。如果没有显示地提供这些属性值,容器会为bean生成一个唯一的name. 然而当你在一个bean中想通过ref属性引用另外的bean,你就必须为那个另外的bean提供一个name了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容