细说Spring——IoC详解(XML配置一)

在我们经过了:

的学习之后,已经对Spring的Ioc容器有了一定的了解,我们队容器如何创建对象有了细致的了解,接下来就是一些其他零零散散的东西,这一期就主要讲解Spring IoC容器的XML配置文件。

一、我们应该怎么理解和认识Spring的配置文件呢?

其实,Spring的配置文件是Spring容器对Bean进行生产以及关系注入的图纸,他是Spring的基础。如果我们没有配置文件的话,则Spring的容器将无从谈起。

Spring 的配置文件是用于指导 Spring 工厂进行 Bean 的生产、依赖关系注入及 Bean 实例分发的“图纸”, J2EE 程序员必须学会并灵活应用这份“图纸”,准确地表达自己的“生产意图”。它是一个或多个标准的XML文档,其ApplicationContext.xml是Spring的默认配置文件,当容器启动时找不到其他的配置文件时,则会尝试加载这个默认的配置文件。

Spring容器成功启动需要以下三方面的条件同时具备:

  • Spring的类包必须已经放在Spring的类容器下面
  • 应用程序应当为Spring提供完备的Bean的配置信息
  • Bean的类都已经放在Spring的类容器下面

Spring启动时读取应用程序提供的Bean的配置信息,并在Spring容器中生成一份相应的Bean的配置注册表,然后根据这张注册表来实例化Bean,装配好Bean之间的依赖关系,为上层应用提供准备就绪的运行环境。
而bean的配置信息就是Bean的元数据信息,他由以下五个方面来组成:

  • Bean的实现类
  • Bean的属性信息 比如:数据源的连接数,用户名和密码等等。
  • Bean的依赖关系 Spring根据依赖关系配置完成Bean之间的装配
  • Bean的行为配置 比如:生命周期范围以及生命周期各个过程的回调函数等
  • Bean的创建方式定义 主要说明是通过构造器还是工厂方法来构造Bean

接下来是他们之间的相互关系:

这里写图片描述

上面这些信息引用自:Spring学习(十二)Spring 的配置文件概述

二、从<beans>标签开始

在我们知道了Spring的配置文件是什么之后,我们就开始自顶向下的逐步讲解Spring的配置文件中的标签,为什么要从<beans>标签开始呢,因为我们每一个类对应到配置文件中都是一个<bean>标签,而多个<bean>标签j就组成了<beans><beans>是XML配置文件中最顶层的元素,它下面可以包含0或者1个<description>和多个<bean>以及<import>或者<alias>,如图所示:

这里写图片描述

<beans>标签可以通过相应的属性对<bean>进行统一的默认行为配置,他的属性有一下几个:

  • default-lazy-init。其值可以指定为true或者false,默认值为false。用来标志是否对所
    有的<bean>进行延迟初始化。
  • default-autowire。可以取值为no、byName、byType、constructor以及autodetect。默
    认值为no,如果使用自动绑定的话,用来标志全体bean使用哪一种默认绑定方式。
  • default-dependency-check。可以取值none、objects、simple以及all,默认值为none,
    即不做依赖检查。
  • default-init-method。如果所管辖的<bean>按照某种规则,都有同样名称的初始化方法的
    话,可以在这里统一指定这个初始化方法名,而不用在每一个<bean>上都重复单独指定。
  • default-destroy-method。与default-init-method相对应,如果所管辖的bean有按照某种
    规则使用了相同名称的对象销毁方法,可以通过这个属性统一指定。

三、<description><import><alias>

1、<description>
可以通过<description>在配置的文件中指定一些描述性的信息。通常情况下,该元素是省略的。当然,如果愿意,<description>随时可以为我们效劳。

2、<import>
通常情况下,可以根据模块功能或者层次关系,将配置信息分门别类地放到多个配置文件中。在想加载主要配置文件,并将主要配置文件所依赖的配置文件同时加载时,可以在这个主要的配置文件中通过<import>元素对其所依赖的配置文件进行引用。比如,如果A.xml中的<bean>定义可能依赖B.xml中的某些<bean>定义,那么就可以在A.xml中使用<import>B.xml引入到A.xml,以类似于<import resource="B.xml"/>的形式。但是,这个功能价值不大,因为容器实际上可以同时加载多个配置,没有必要非通过一 个配置文件来加载所有配置。不过,或许在有些场景中使用这种方式比较方便也说不定。

3、<alias> 可以通过<alias>为某些<bean>起一些“外号”(别名),通常情况下是为了减少输入。比如,假设有个<bean>,它的名称为dataSourceForMasterDatabase,你可以为其添加一个<alias>,像这样<alias name="dataSourceForMasterDatabase" alias="masterDataSource"/>。以后通过dataSourceForMasterDatabase或者masterDataSource来引用这个<bean>都可以,只要你觉得方便就行。

四、最重要的<bean>标签

首先我们来看一下如何定义一个<bean>标签:

<bean id="djNewsListener" class="..impl.DowJonesNewsListener">
</bean> 

然后我们就来学习一下<bean>标签中的属性:
1、id属性:我们通过id属性来作为唯一标识,也就是起一个名字,相当于这个<bean>的名字。id的命名规则:

  • 遵循XML命名规范
  • 由字母,数字,下划线组成
  • 驼峰式,首个单词字母小写,从第二个单词开始首字母大写。

2、name属性:是不是有点糊涂了,既然有name属性,我们为啥还要id属性,其实name属性基本已经不用了,所以我们通过id来当做名字就可以了。
3、class属性:每个注册到容器的对象都需要通过<bean>元素的class属性指定其类型,否则,容器可不知道这个对象到底是何方神圣。在大部分情况下,该属性是必须的。

五、<bean>标签下的子标签

1、<constructor-arg>:我们可以通过这个标签进行依赖对象的构造器注入,示例如下:
<bean id="djNewsProvider" class="..FXNewsProvider">
     <constructor-arg>
         <ref bean="djNewsListener"/>
     </constructor-arg>
     <constructor-arg>
         <ref bean="djNewsPersister"/>
     </constructor-arg>
</bean> 

从这个实例中我们可以看出djNewsProvider这个bean中有两个依赖对象,和以这两个依赖对象为参数的构造方法,两个对象分别是:djNewsListenerdjNewsPersister。其中的<ref>标签我们马上讲解。

<constructor-arg>标签中有两个属性:

  • type属性:假如一个类中有两个构造方法,那么我们就可以使用type属性来指定调用构造方法的参数类型,这样就可以按照自己的喜好来指定构造方法。示例如下:
<bean id="mockBO" class="..MockBusinessObject">
     <constructor-arg type="int">
         <value>111111</value>
     </constructor-arg>
</bean> 

这里指定调用了构造器参数为int类型的构造器。

  • index属性:当当前<bean>对象的构造器有多个相同参数的构造方法时,我们就可以是有index标签来指定构造器方法的参数顺序。示例如下:
<bean id="mockBO" class="..MockBusinessObject">
     <constructor-arg index="1" value="11111"/>
     <constructor-arg index="0" value="22222"/>
</bean> 

这里我们就指定了第一个参数的值为22222,第二个参数的值为11111

2、<property>:我们可以通过这个标签来进行setter方法的依赖注入,示例如下:
<bean id="djNewsProvider" class="..FXNewsProvider"> 2
     <property name="newsListener">
         <ref bean="djNewsListener"/>
    </property>
     <property name="newPersistener">
         <ref bean="djNewsPersister"/>
     </property>
</bean>

这里的一个<property>就对应一个属性的setter方法。

<property>标签有一个name属性,用来指定当前对象的属性名称。

六、<property><constructor-arg>下的子标签

1、<value>

可以通过<value>为主体对象注入简单的数据类型,不但可以指定String类型的数据,而且可以指定其他Java语言中的原始类型以及它们的包装器(wrapper)类型,比如int、Integer等。容器在注入的时候,会做适当的转换工作(我们其实已经知道做这个工作的就是PropertyEditor)
我们可以通过以下两种用法来使用<value>标签:

第一种
<constructor-arg>
     <value>111111</value>
</constructor-arg>
<property name="attributeName">
     <value>222222</value>
</property> 
第二种
<constructor-arg value="111111"/>
<property name="attributeName" value="222222"/> 
2、<ref>

使用<ref>来引用容器中其他的对象实例,可以通过<ref>localparentbean属性来指定引用的对象的beanName是什么。示例如下:

constructor-arg>
     <ref local="djNewsPersister"/>
</constructor-arg>
或者
<constructor-arg>
     <ref parent="djNewsPersister"/>
</constructor-arg>
或者
<constructor-arg>
     <ref bean="djNewsPersister"/>
</constructor-arg> 

localparentbean的区别在于:

  • local只能指定与当前配置的对象在同一个配置文件的对象定义的名称(可以获得XML解析器的id约束验证支持
  • parent则只能指定位于当前容器的父容器中定义的对象引用
  • bean则基本上通吃,所以,通常情况下,直接使用bean来指定对象引用就可以了
3、<idref>

<idref>我可以获取spring容器中的bean的name的值(一个字符串),而不是bean的实例。
<idref>元素的功能与<value>类似,就是<idref>多了验证的功能,减少配置的书写错误机率。
总之就是一句话,在我们需要spring容器中的bean的name的值时,使用<idref>标签。

4、内部<bean>

使用<ref>可以引用容器中独立定义的对象定义。但有时,可能我们所依赖的对象只有当前一个对象引用,或者某个对象定义我们不想其他对象通过<ref>引用到它。这时,我们可以使用内嵌的<bean>,将这个私有的对象定义仅局限在当前对象。示例如下:

<bean id="djNewsProvider" class="..FXNewsProvider">
     <constructor-arg index="0">
         <bean class="..impl.DowJonesNewsListener">
     </bean>
     </constructor-arg> 
     <constructor-arg index="1">
         <ref bean="djNewsPersister"/>
     </constructor-arg>
</bean> 
5、<list><set><map>

这三个标签我们一看就能知道他们对应的是集合类型的参数。这里就不多举例子了,如果有疑问可以参考:Spring学习笔记(一)——IOC

6、<props>

<props>是简化后了的<map>,该元素对应配置类型为java.util.Properties的对象依赖。因为Properties只能指定String类型的键(key)和值,所以,<props>的配置简化很多,示例如下:

<property name="valueSet">
     <props>
         <prop key="author">fujohnwang@gmail.com</prop>
         <prop key="support">support@spring21.cn</prop>
         ...
     </props>
</property> 

感觉内容实在太多了,这一次就到这里吧,接下来的一起,将会详细讲解<bean>中的属性和其他的一些内容。

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • 1.1 spring IoC容器和beans的简介 Spring 框架的最核心基础的功能是IoC(控制反转)容器,...
    simoscode阅读 6,699评论 2 22
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,736评论 6 342
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong阅读 22,306评论 1 92
  • 把事情做好的前提不是一个人有多能耐,而是需要你的团队互相之间默契的配合,协作的重要性不单体现在工作中,婚姻亦然。 ...
    8ab1b259aed0阅读 415评论 0 3