本文借鉴:Spring学习(特此感谢!)

一、配置Bean的方式及选择

配置方式

  • 在 XML 文件中显式配置
  • 在 Java 的接口和类中实现配置
  • 隐式 Bean 的发现机制和自动装配原则

方式选择的原则

最优先:通过隐式 Bean 的发现机制和自动装配的原则。

基于约定优于配置的原则,这种方式应该是最优先的

  • 好处:减少程序开发者的决定权,简单又不失灵活。

其次:Java 接口和类中配置实现配置

在没有办法使用自动装配原则的情况下应该优先考虑此类方法

  • 好处:避免 XML 配置的泛滥,也更为容易。
  • 典型场景:一个父类有多个子类,比如学生类有两个子类,一个男学生类和女学生类,通过 IoC 容器初始化一个学生类,容器将无法知道使用哪个子类去初始化,这个时候可以使用 Java 的注解配置去指定。

最后:XML 方式配置

在上述方法都无法使用的情况下,那么也只能选择 XML 配置的方式。

好处:简单易懂(当然,特别是对于初学者)

典型场景:当使用第三方类的时候,有些类并不是我们开发的,我们无法修改里面的代码,这个时候就通过 XML 的方式配置使用了。

二、通过 XML 配置装配 Bean

1、XML配置前言

使用 XML 装配 Bean 需要定义对应的 XML,这里需要引入对应的 XML 模式(XSD)文件,这些文件会定义配置 Spring Bean 的一些元素,当我们在 IDEA 中创建 XML 文件时,会有友好的提示:

一个简单的 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"></beans>

这就只是一个格式文件,引入了一个 beans 的定义,引入了 xsd 文件,它是一个根元素,这样它所定义的元素将可以定义对应的 Spring Bean。

2、装配简易值

先来一个最简单的装配:

<bean id="c" class="pojo.Category"><property name="name" value="测试" />
</bean>

简单解释一下:

  id 属性是 Spring 能找到当前 Bean 的一个依赖的编号,遵守 XML 语法的 ID 唯一性约束。必须以字母开头,可以使用字母、数字、连字符、下划线、句号、冒号不能以/开头

   name 属性也可以定义 bean 元素的名称,能以逗号或空格隔开起多个别名,并且可以使用很多的特殊字符,比如在 Spring 和 Spring MVC 的整合中,就得使用 name 属性来定义 bean 的名称,并且使用 /开头。

  class 属性显然就是一个类的全限定名

  property 元素是定义类的属性,其中的 name 属性定义的是属性的名称,而 value 是它的值。

  PS: 从 Spring 3.1 开始,id 属性也可以是 String 类型了,也就是说 id 属性也可以使用 / 开头,而 bean 元素的 id 的唯一性由容器负责检查。

  PS:如果 id 和 name 属性都没有声明的话,那么 Spring 将会采用 “全限定名#{number}” 的格式生成编号。 例如这里,如果没有声明 “id="c"” 的话,那么 Spring 为其生成的编号就是是“pojo.Category#0”,当它第二次声明没有 id 属性的 Bean 时,编号就是 “pojo.Category#1”,以此类推。

  这样的定义很简单,但是有时候需要注入一些自定义的类,比如之前饮品店的例子,JuickMaker 需要用户提供原料信息才能完成 juice 的制作:

<!-- 配置 srouce 原料 -->
<bean name="source" class="pojo.Source"><property name="fruit" value="橙子"/><property name="sugar" value="多糖"/><property name="size" value="超大杯"/>
</bean><bean name="juickMaker" class="pojo.JuiceMaker"><!-- 注入上面配置的id为srouce的Srouce对象 --><property name="source" ref="source"/>
</bean>

  这里先定义了一个 name 为 source 的 Bean,然后再制造器中通过 ref 属性去引用对应的 Bean,而 source 正是之前定义的 Bean 的 name ,这样就可以相互引用了。

  •ref 引用对象

3、装配集合

  有些时候我们需要装配一些复杂的东西,比如 Set、Map、List、Array 和 Properties 等,为此我们在 Packge【pojo】下新建一个 ComplexAssembly 类:

package pojo;import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;public class ComplexAssembly {private Long id;private List<String> list;private Map<String, String> map;private Properties properties;private Set<String> set;private String[] array;/* setter and getter */
}

  这个 Bean 没有任何的实际意义,只是为了介绍如何装配这些常用的集合类:

<bean id="complexAssembly" class="pojo.ComplexAssembly"><!-- 装配Long类型的id --><property name="id" value="1"/><!-- 装配List类型的list --><property name="list"><list><value>value-list-1</value><value>value-list-2</value><value>value-list-3</value></list></property><!-- 装配Map类型的map --><property name="map"><map><entry key="key1" value="value-key-1"/><entry key="key2" value="value-key-2"/><entry key="key3" value="value-key-2"/></map></property><!-- 装配Properties类型的properties --><property name="properties"><props><prop key="prop1">value-prop-1</prop><prop key="prop2">value-prop-2</prop><prop key="prop3">value-prop-3</prop></props></property><!-- 装配Set类型的set --><property name="set"><set><value>value-set-1</value><value>value-set-2</value><value>value-set-3</value></set></property><!-- 装配String[]类型的array --><property name="array"><array><value>value-array-1</value><value>value-array-2</value><value>value-array-3</value></array></property>
</bean>

总结:

  • List 属性为对应的 <list> 元素进行装配,然后通过多个 <value> 元素设值
  • Map 属性为对应的 <map> 元素进行装配,然后通过多个 <entry> 元素设值,只是 entry 包含一个键值对(key-value)的设置
  • Properties 属性为对应的 <properties> 元素进行装配,通过多个 <property> 元素设值,只是 properties 元素有一个必填属性 key ,然后可以设置值
  • Set 属性为对应的 <set> 元素进行装配,然后通过多个 <value> 元素设值
  • 对于数组而言,可以使用 <array> 设置值,然后通过多个 <value> 元素设值。

  上面看到了对简单 String 类型的各个集合的装载,但是有些时候可能需要更为复杂的装载,比如一个 List 可以是一个系列类的对象,为此需要定义注入的相关信息,其实跟上面的配置没什么两样,只不过加入了 ref 这一个属性而已。

集合注入总结:

  • List 属性使用 <list> 元素定义注入,使用多个 <ref> 元素的 Bean 属性去引用之前定义好的 Bean
<property name="list"><list><ref bean="bean1"/><ref bean="bean2"/></list>
</property>

  • Map 属性使用 <map> 元素定义注入,使用多个 <entry> 元素的 key-ref 属性去引用之前定义好的 Bean 作为键,而用 value-ref 属性引用之前定义好的 Bean 作为值
<property name="map"><map><entry key-ref="keyBean" value-ref="valueBean"/></map>
</property>

  • Set 属性使用 <set> 元素定义注入,使用多个 <ref> 元素的 bean 去引用之前定义好的 Bean
<property name="set"><set><ref bean="bean"/></set>
</property>

4、命名空间装配

  除了上述的配置之外, Spring 还提供了对应的命名空间的定义,只是在使用命名空间的时候要先引入对应的命名空间和 XML 模式(XSD)文件。

c-命名空间(constructor,配置构造器的参数)

  c-命名空间是在 Spring 3.0 中引入的,它是在 XML 中更为简洁地描述构造器参数的方式,要使用它的话,必须要在 XML 的顶部声明其模式:

PS:是通过构造器参数的方式

  现在假设我们现在有这么一个类:

package pojo;public class Student {int id;String name;public Student(int id, String name) {this.id = id;this.name = name;}// setter and getter
}

  在 c-命名空间和模式声明之后,我们就可以使用它来声明构造器参数了:

<!-- 引入 c-命名空间之前 -->
<bean name="student1" class="pojo.Student"><constructor-arg name="id" value="1" /><constructor-arg name="name" value="学生1"/>
</bean><!-- 引入 c-命名空间之后 -->
<bean name="student2" class="pojo.Student"c:id="2" c:name="学生2"/>

  c-命名空间属性名以 “c:” 开头,也就是命名空间的前缀。接下来就是要装配的构造器参数名,在此之后如果需要注入对象的话则要跟上 -ref(如c:card-ref="idCard1",则对 card 这个构造器参数注入之前配置的名为 idCard1 的 bean)

  很显然,使用 c-命名空间属性要比使用 <constructor-arg> 元素精简,并且会直接引用构造器之中参数的名称,这有利于我们使用的安全性。

  我们有另外一种替代方式:

<bean name="student2" class="pojo.Student" c:_0="3" c:_1="学生3"/>

  我们将参数的名称替换成了 “0” 和 “1” ,也就是参数的索引。因为在 XML 中不允许数字作为属性的第一个字符,因此必须要添加一个下划线来作为前缀。

p-命名空间(property,配置构造器的参数)

  c-命名空间通过构造器注入的方式来配置 bean,p-命名空间则是用setter的注入方式来配置 bean ,同样的,我们需要引入声明:

  然后我们就可以通过 p-命名空间来设置属性:

<!-- 引入p-命名空间之前 -->
<bean name="student1" class="pojo.Student"><property name="id" value="1" /><property name="name" value="学生1"/>
</bean><!-- 引入p-命名空间之后 -->
<bean name="student2" class="pojo.Student" p:id="2" p:name="学生2"/>

  我们需要先删掉 Student 类中的构造函数,不然 XML 约束会提示我们配置 <constructor-arg> 元素。

  同样的,如果属性需要注入其他 Bean 的话也可以在后面跟上 -ref:

<bean name="student2" class="pojo.Student" p:id="2" p:name="学生2" p:cdCard-ref="cdCard1"/>

util-命名空间

  工具类的命名空间,可以简化集合类元素的配置,同样的我们需要引入其声明(无需担心怎么声明的问题,IDEA会有很友好的提示):

  我们来看看引入前后的变化:

<!-- 引入util-命名空间之前 -->
<property name="list"><list><ref bean="bean1"/><ref bean="bean2"/></list>
</property><!-- 引入util-命名空间之后 -->
<util:list id="list"><ref bean="bean1"/><ref bean="bean2"/>
</util:list>

  下表提供了 util-命名空间提供的所有元素:

5、引入其他配置文件

在实际开发中,随着应用程序规模的增加,系统中 <bean> 元素配置的数量也会大大增加,导致 applicationContext.xml 配置文件变得非常臃肿难以维护。

解决方案

applicationContext.xml 文件包含其他配置文件即可 使用 <import> 元素引入其他配置文件

【1】在【src】文件下新建一个 bean.xml 文件,写好基础的约束,把 applicationContext.xml 文件中配置的 <bean> 元素复制进去

【2】在 applicationContext.xml 文件中写入

<import resource="bean.xml" />

【3】运行测试代码,仍然能正确获取到 bean

转载于:https://www.cnblogs.com/riches/p/11520090.html

Spring学习(五)bean装配详解之 【XML方式配置】相关推荐

  1. Spring学习(七)bean装配详解之 【通过注解装配 Bean】【自动装配的歧义解决】...

    本文借鉴:Spring学习,@Bean 的用法(特此感谢!) 自动装配 1.歧义性 我们知道用@Autowired可以对bean进行注入(按照type注入),但如果有两个相同类型的bean在IOC容器 ...

  2. Spring学习(六)bean装配详解之 【通过注解装配 Bean】【基础配置方式】

    本文借鉴:Spring学习(特此感谢!) 通过注解装配 Bean 1.前言 优势 1.可以减少 XML 的配置,当配置项多的时候,XML配置过多会导致项目臃肿难以维护 2.功能更加强大,既能实现 XM ...

  3. spring学习之@ModelAttribute运用详解

    @ModelAttribute使用详解 1.@ModelAttribute注释方法      例子(1),(2),(3)类似,被@ModelAttribute注释的方法会在此controller每个方 ...

  4. Spring中的bean标签详解

    文章目录 Bean标签基本配置 Bean标签范围配置 Bean生命周期配置 Bean的依赖注入入门 Bean的依赖注入概念 Bean的依赖注入方式 Bean的依赖注入的数据类型 引入其他配置文件(分模 ...

  5. 面渣逆袭:Spring三十五问,四万字+五十图详解

    基础 1.Spring是什么?特性?有哪些模块? 一句话概括:Spring 是一个轻量级.非入侵式的控制反转 (IoC) 和面向切面 (AOP) 的框架. 2003年,一个音乐家Rod Johnson ...

  6. 面渣逆袭:Spring三十五问,四万字+五十图详解 。不要错过

    基础 1.Spring是什么?特性?有哪些模块? Spring Logo 一句话概括:Spring 是一个轻量级.非入侵式的控制反转 (IoC) 和面向切面 (AOP) 的框架. 2003年,一个音乐 ...

  7. java spring bean配置文件_Spring基于xml文件配置Bean过程详解

    这篇文章主要介绍了spring基于xml文件配置Bean过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 通过全类名来配置: class:be ...

  8. Spring第三天,详解Bean的生命周期,学会后让面试官无话可说!

    点击下方链接回顾往期 不要再说不会Spring了!Spring第一天,学会进大厂! Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官! 今天讲解Spring中Bean的生命周期. ...

  9. 面渣逆袭:Spring三十五问,四万字+五十图详解,建议收藏。

    这节我们来搞定另一个面试必问知识点--Spring. 有人说,"Java程序员都是Spring程序员",老三不太赞成这个观点,但是这也可以看出Spring在Java世界里举足轻重的 ...

最新文章

  1. 成功解决AttributeError: module tensorflow.compat has no attribute v1
  2. MPLS TE基本配置-OSPF
  3. 全球唯一标识符:GUID在线生成
  4. 中国双光束紫外可见分光光度计行业市场供需与战略研究报告
  5. js原生ajax跨域请求,封装一个原生js的ajax请求,支持IE9CORS跨域请求
  6. 2020-01-14 IP/TCP/UDP 对应的RFC编号
  7. 下载python教程-零基础Python教程全集下载.pdf
  8. linux cuda 安装目录,Ubuntu16.04 CUDA和GPU的最简最全安装方案及常见问题解决方法,G...
  9. Unity3D AI:导航系统-导航网格生成
  10. 一个基于ATMEGA128的直流电机抱死程序
  11. ubuntu linux拼音输入法,Ubuntu 中文拼音输入法小结
  12. Node.jsv12.0 https请求报错
  13. 低代码搭建门店管理之收发货管理系统
  14. 在更改计算机的设置路由器,怎么改路由器wifi密码 怎么修改路由器wifi密码
  15. 电脑突然关机重启是什么原因?
  16. 黑客入侵微软邮件服务器部署勒索软件、惠普更新打印机漏洞|12月2日全球网络安全热点
  17. 达芬奇大王的链表贪吃蛇(java)
  18. Python网络数据采集知识点
  19. Python搞不定蝴蝶图?
  20. SecureCRT上如何下载文件

热门文章

  1. python计时器代码_用Python写计时器
  2. pixhawk PX4FMU和PX4IO最底层启动过程分析
  3. POJ-3067 Japan(树状数组、线段树)
  4. 网络流 (EK Dinic)
  5. ubuntu切换python,以及切换python后相关包的管理
  6. c++ 该使用类内初始值么?
  7. java sorted排序_【算法】排序算法之计数排序
  8. 客户信息管理系统——Java
  9. html设计一张试卷算分,HTML试卷10班分享[共5页].doc
  10. linux查看上次重启日志和ip,Linux實時查看日志,訪問前10IP 和相關命令