3.Spring XML元素的具体使用

目录


Spring专栏目录(点击进入…)



Spring XML元素的具体使用

作为Spring核心机制的依赖注入,改变了传统的编程习惯,对组件的实例化不再由应用程序完成,转而交由Spring容器完成,在需要时注入应用程序中,从而对组件之间依赖关系进行了解耦。这一切都离不开Spring配置文件中使用的<bean>元素。

Spring 容器可以被看作一个大工厂,而Spring容器中的Bean就相当于该工厂的产品。如果希望这个大工厂能够生产和管理Bean,这时则需要告诉容器需要哪些Bean,以及需要以何种方式将这些Bean装配到一起。


Spring配置文件支持两种不同的格式

(1)XML文件格式

通常情况下,Spring会以XML文件格式作为Spring的配置文件,这种配置方式通过XML文件注册并管理Bean之间的依赖关系

XML格式配置文件的根元素是<beans>,该元素包含了多个<bean>子元素,每一个<bean>子元素定义了一个Bean,并描述了该Bean如何被装配到Spring容器中

beans

特点:最顶级元素,包含多个<bean>

属性描述
default-lazy-init用于设置<bean>延迟初始化。默认false
default-autowire控制全体bean采用哪种默认绑定。取值no/byName/byType/constructor/。默认为no
default-destroy-method指定管理的bean的销毁方法
default-init-method指定管理的bean的初始化方法

统一管理bean,避免重复指定bean的创建规则。

description(说明)

一般是省略的。可以为配置文件添加描述性话语。

import

导入其它配置文件

<import resource="applicationContext-dao.xml/>
alias

设置别名

<bean id="onBean" class=""></bean>
<alias name="onBean" alias="a"/>

给名为onBean的bean设置别名为a,此后可以使用a或者onBean访问该bean。


(2)Properties文件格式



beans子元素bean(重点)

属性描述
id唯一标识符,Spring容器对Bean的配置和管理都通过该属性完成
name用来为id创建一个或多个别名。可以是任意的字母符合。多个别名之间用逗号或空格分开
class用来定义类的全限定名(包名+类名)。只有子类Bean不用定义该属性
scope用于设定Bean实例的作用域。singleton(单例)、prototype(原型)、request、session和global Session。默认singleton
parent子类Bean定义它所引用它的父类Bean。这时前面的class属性失效。子类Bean会继承父类Bean的所有属性,子类Bean也可以覆盖父类Bean的属性。注意:子类Bean和父类Bean是同一个Java类
abstract用来定义Bean是否为抽象Bean。表示这个Bean将不会被实例化,一般用于父类Bean,因为父类Bean主要是供子类Bean继承使用。默认false
singleton定义Bean是否是Singleton(单例)。设为true,则在BeanFactory作用范围内,只维护此Bean的一个实例。设为flase,Bean将是Prototype(原型)状态,BeanFactory将为每次Bean请求创建一个新的Bean实例。默认为true
lazy-init用来定义这个Bean是否实现懒初始化。true。它将在BeanFactory启动时初始化所有的Singleton Bean。false。它只在Bean请求时才开始创建Singleton Bean。默认为“default”
depends-on这个Bean在初始化时依赖的对象,这个对象会在这个Bean初始化之前创建。依赖对象
init-method用来定义Bean的初始化方法,会在Bean组装之后调用。必须是一个无参数方法
destroy-method用来定义Bean的销毁方法,它在BeanFactory关闭时调用。必须是一个无参数方法。只能应用于Singleton Bean
factory-method定义创建该Bean对象的工厂方法。用于下面的“factory-bean”,表示这个Bean是通过工厂方法创建。此时此bean的class属性失效
factory-bean定义创建该Bean对象的工厂类。如果使用了“factory-bean”则class属性失效

scope(作用域)

bean的scope属性,除了可以创建Bean实例并对Bean的属性进行诸如外,还可以为所定义的Bean指定一个作用域。作用域的取值决定了Spring创建该组件实例的策略,进而影响程序的运行效率和数据安全。
Spring容器支持自定义scope。需要实现接口org.springframework.beans.factory.config.Scope

XML

singleton是默认采用的作用域,即默认情况下Spring为每个Bean仅创建一个实例。对于不存在线程安全问题的组件,采用这种方式可以大大减少创建对象的开销,提高运行效率

对于存在线程安全问题的组件,则不能使用singleton模式,可以使用prototype作用域,通过scope属性

<bean id="" class="" scope="prototype"></bean>

每次获取该组件时,都会创建一个新的实例,避免因为共用同一个实例而产生线程安全问题

作用域说明
singleton以单例模式创建Bean的实例,即容器中该Bean的实例只有一个。默认
prototype每次从容器中获取Bean时,都会创建一个新的实例
request用于Web应用环境,针对每次HTTP请求都会创建一个实例
seesion用于Web应用环境中使用,同一个全局会话共享一个实例
global session仅在Protlet的Web应用中使用,同一个全局会话共享一个实例。对于非Portlet环境,等同于session

注解

对于使用注解声明的Bean组件,如需修改其作用域,可以使用@Scope注解实现

@Scope("prototype")

## autowire(自动注入) 除开使用配置明确指出依赖关系,还可以使用autowire自动绑定的功能。(非标签方式也可以使用)。这样可以减少手工输入的工作量。Spring提供了4种自动绑定的模式。
参数描述
no不使用自动装配功能。默认
byName通过Bean的属性名(name)实现自动装配。与xml文件中配置的bean name进行匹配。匹配符合的bean定义会被自动绑定到当前实例变量上。适用于setter注入方式
byType通过Bean的类型实现自动装配。类似byName模式,只是从beanName的判定到beanType判定自动绑定。适用于setter注入方式
constructor构造函数的参数的自动组装。constructor指定的是按beanType的自动绑定过程

注意:自动注入的时候如果找不到对应的bean则不进行注入,当找到对应的时候,则会注入,当找到多个可注入对象的时候,因无法判断该注入哪个值会发生异常,因而还是推荐使用手动指定依赖关系。

可以使用< beans >的属性default-autowire指定beans管理下所有bean的自动注入方式(一般不推荐)


dependency-check(依赖检查)

用来确保Bean组件通过JavaBean描述的所以依赖关系都得到满足。在与自动装配功能一起使用时,它特别有用。

属性描述
none不进行依赖检查
objects只做对象间依赖的检查
simple只做原始类型和String类型依赖的检查
all对所有类型的依赖进行检查。包括了前面的objects和simple

lazy-init(延迟加载)

主要针对于applicationContext类型的容器初始化,bean的加载策略,通常对于applicationContext容器在容器启动的时候会马上对所有singleton类型的bean进行实例化加载

当想修改这个行为可以使用lazy-init属性加以限制。但是并非指定了lazy-init就一定会延迟加载。未延迟加载的bean对延迟加载的bean存在依赖关系时候,则还是会一开始便初始化设定了延迟加载规则的bean。

可以使用<beans>中的属性default-lazy-init对beans下的bean进行统一的加载策略设置


parent、abstract(继承关系)

使用场景:继承关系下,属性继承父类的bean的属性,特定的属性额外配置其值。与Java继承不同的是,此处继承的是属性的值,Java继承的属性跟方法。不同于Java继承的纵向继承。常规写法需要对子类重复赋值会存在冗余的情况,因而可以考虑使用xml中bean继承。

<bean id="parentBean" class="com.my.beans.Message">
	<property name="a" ref="a"></property>
	<property name="b" value="223344"></property>
</bean>

<bean id="children1" class="com.my.beans.Message" parent="parentBean">
	<property name="b" value="this is children C"></property>
</bean>

<bean id="children2" class="com.my.beans.Message" parent="parentBean">
	<property name="b" value="this is children D"></property>
</bean>

子元素

public class Human {
	private String name;
	private String password;
	private Map<String, String> map = new HashMap<String, String>();
	private Map<String, Book> maps = new HashMap<String, Book>();
	private List<String> list = new ArrayList<String>();
	private Set<String> set = new HashSet<String>();

	public Human(String name, String password) {
		this.name = name;
		this.password = password;
	}

	public Human(String name, String password, Map<String, String> map) {
		this.name = name;
		this.password = password;
		this.map = map;
	}
}

constructor -arg

配合bean使用,用于使用构造方式处理对象之间依赖关系。当对象中存在多个构造方法的时候,而且请求参数列表数目,类型不同时候,需要使用内部的属性协助。

<bean id="human" class="com.my.Human">
	<constructor-arg type="string">
		<value>name</value>
	</constructor-arg>
	
	<constructor-arg type="string">
		<value>password</value>
	</constructor-arg>
</bean>
构造属性描述
type指定构造对象参数的注入类型,由于在xml配置时候,会将普通的入参默认当做字符串处理,因而在这种情况下也可以使用type指定其类型。避免出错
index当类型也一致时候可以使用index指定入参的顺序,控制bean的依赖注入关系。需要注意的是使用index的时候起始下标是从0开始的
value可以作为一个属性写入也可以作为子标签在< constructor-arg >中使用

property

用于处理setter依赖关系的关系注入

<bean id="human" class="com.my.Human">
	<property name="name" value="user"></property>
	<property name="password" value="admin"></property>
</bean>

对于基本数据类型及其包装类、字符串,除了可以使用value属性,还可以通过<property>的<value>子元素进行注入。

属性描述
name属性名对应
value
ref引用哪个bean

引用其他Bean组件
Bean可以相互引用,从而建立以来关系,除了使用ref属性,还可以通过<property>的<ref>子元素实现

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

property与constructor-arg中的可配置项

构造属性描述
value可以通过value为主体注入简单数据类型。可以指定String与基本类型+基本类型的包装类型。容器在注入的时候会做适当的转换工作,这个是最底层元素,无法再嵌套别的元素了
ref使用ref引用容器中的其它对象实例。有三种引用范围可以选择:local,parent,bean;local只能指定与当前配置对象在同一配置文件下的bean对象;parent只能指定当前容器父容器定义的对象引用;bean均可以指定到。同< value>标签一致,它也是一个底层标签不能内嵌标签

使用p命名空间(p:属性)

Spring配置文件从2.0开始采用schema形式,使用不同的命名空间管理不同类型的配置,使得配置文件更具有扩展性。为许多领域的问题提供了简化的配置方法,大大简化了配置的工作量

特点:使用属性而不是子元素的形式配置Bean的属性,从而简化了Bean的配置。

(1)对于直接量(基本数据类型、字符串)属性

语法:p:属性名=”属性值”;

<bean id="human" class="com.my.Human" p:name="one"/>
(2)对于引用Bean属性

语法:p:属性名-ref=”Bean的id”

<bean id="human" class="com.my.Human" p:list-ref="oneList"/>

注入不同的数据类型:Spring提供了不同标签来实现各种不同类型参数的注入,这些标签对于设值注入和构造注入都适用


idref

为当前对象注入所依赖对象的名称,而不是引用,最适合的方式是使用idref,这个标签可以在容器解析配置时候,帮助检查bean Name是否存在。

<bean id="human" class="com.my.Human">
	<property name="a">
		<idref bean="x"></idref>
	</property>
</bean>

注意:是名称不是引用,此方法注入的值一定是String,而且是已经在容器中托管的bean中的一个bean Name

因为在程序中bean与bean之间经常需要互相访问,才能完成应用程序的功能,要想bean与bean之间互相访问,就必须在bean配置文件中指定对bena的引用,可以使用ref标签来进行引用或者ref属性进行引用。


内部bean

如果一个Bean组件仅在一处需要使用,可以把它定义为内部Bean

定义的bean是私有的时候使用;不能被外部引用,只能在内部使用。仅仅给一个特定的属性使用,不需要设置任何id或者name,不只是属性注入可以使用内部Bean 构造器注入也可以

<bean id="human" class="com.my.Human">
	<constructor-arg>
		<bean class="com.my.One"></bean>
	</constructor-arg>
</bean>

因为只供内部使用,所以可以不设置id的值


外部Bean

ref属性、ref标签

<!-- 外部bean -->
<bean id="human" class="com.my.Human" p:school-ref="sch" />

list

对应注入对象类型为list类型及其子类或者数组类型的依赖对象

<bean id="human" class="com.my.Human">
	<property name="list">
		<list>
			<value>one</value>
			<value>two</value>
			<value>three</value>
		</list>
	</property>
</bean>

set

注入一组无序的依赖。对set而言,元素顺序无关紧要。对应注入的依赖是set及其子类的依赖对象。

<bean id="human" class="com.my.Human">
	<property name="set">
		<set>
			<value>1</value>
		</set>
	</property>
</bean>

map

注入map及其子类类型依赖对象,使用该标签。该标签下有子标签< entry>

<bean id="human" class="com.my.Human">
	<property name="map">
		<map>
		<entry key="first">
			<value>first value</value>
		</entry>
		<entry key="second">
			<ref bean="property"/>
		</entry>
		<entry key-ref="property" value="property bean"></entry>
		<entry key-ref="a" value-ref="property"></entry>
		</map>
	</property>
</bean>

props

< props>是简化的< map>,但是不同于< map>,只能注入String类型的数据,< prop >中有且仅有key属性,不能内嵌别的标签

<bean id="human" class="com.my.Human">
	<property name="list">
		<props>
			<prop key="author1">作者1</prop>
			<prop key="author2">作者2</prop>
			<prop key="author3">作者3</prop>
		</props>
	</property>
</bean>

< null/>

注入null值时候使用,需要注意的是< value></ value >注入的值是空字符串,不是null值


特殊字符:<![CDATA[ ]]>

如果属性值中包含了XML中的特殊字符,则注入时需要进行处理

以采用两种办法:

(1)使用<![CDATA[ ]]>标签封装包含特殊字符的字符串

<property name="name">
	<value><![CDATA[/search?keyword=key&timestamp=1024]]></value>
</property>

(2)XML预定义实体引用

符号实体引用符号实体引用
<&It;&apos;
>$gt;&quot;
&&amp;
<property name="uri" value="/search?keyword=key&amp;timestamp=1024" />
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未禾

您的支持是我最宝贵的财富!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值