内容参考自spring in action一书。

创建应用对象之间协作关系的行为通常称为装配,这也是依赖注入的本质。

1. 创建spring配置

spring是一个基于容器的框架。如果没有配置spring,那么它就是一个空的容器,所以需要配置spring来告诉容器它需要加载哪些Bean和如何装配这些bean,这样才能确保它们能够彼此协作。

从spring3.0开始,spring容器提供了两种配置bean的方式。第一种是传统上的使用一个或多个XML文件作为配置文件。第二种提供了基于java注解的配置方式。

先说XML文件的配置方式:

在XML文件中声明Bean时,Spring配置文件的根元素是来源于Spring Beans命名空间所定义的<beans>元素。下面是一个典型的Spring 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-3.0.xsd">
<!-- Bean declarations go here -->
</beans>

在<beans>元素内可以放置所有的Spring配置信息,包括<bean>元素的声明。但是beans的命名空间并不是唯一的Spring命名空间。Spring的核心框架自带了10个命名空间配置。如下所示:

2. 注入bean属性

spring注入bean属性有三种方式,常用的有两种,第一种是通过构造器注入。第二种是通过Setter注入。

第一种,通过构造器注入:

先看最简单的构造器注入方式,通过默认构造函数进行注入。

    <bean id="duke" class="com.pcitc.springInAction.Juggler" />

2.1.1 通过构造器注入简单值:

现在进行按需实例化,不走默认的构造方法:

<bean id="duke" class="com.pcitc.springInAction.Juggler">
<constructor-arg value="15" />
</bean>

总结:在构造bean的时候可以使用 <constructor-arg>元素来告诉spring额外的信息。如果不配置 <constructor-arg>元素,那么spring将使用默认的构造方法,上面配置了 <constructor-arg>的value属性设置为15,Spring将调用Juggler的另一个构造方法。

2.1.2 通过构造器注入对象引用:

<bean id="sonnet29" class="com.pcitc.springInAction.Sonnet29" />
<bean id="poeticDuke" class="com.pcitc.springInAction.PoeticJuggler">
<constructor-arg value="15" />
<constructor-arg ref="sonnet29" />
</bean>

总结: <constructor-arg ref="sonnet29" />,把bean引用传递给构造器,当spring碰到sonnet29和duke的声明时,它所执行的逻辑本质上和下面的java代码相同:

Poem sonnet29 = new Sonnet29();
Performer duke = new PoeticJuggler(15, sonnet29);

通过工厂方法创建Bean:

假如想声明的Bean没有一个公开的构造方法,那怎么办呢?方法是通过工厂方法创建bean。

有时候静态工厂方法是实例化对象的唯一方法。Spring支持通过<bean>元素的factory-method属性来装配工厂创建的bean。

定义一个单例类:

package com.pcitc.springInAction;

public class Stage {
private Stage() {
} private static class StageSingletonHolder {
static Stage instance = new Stage();
} public static Stage getInstance() {
return StageSingletonHolder.instance;
}
}

Stage类没有一个公开的构造方法,这时候只能通过Spring的factory-method属性调用一个指定的静态方法,从而代替构造方法来创建一个类的实例。

在Spring配置文件下这样来声明该bean

<bean id="theStage" class="com.pcitc.springInAction.Stage"
factory-method="getInstance" />

第二种,通过Setter方法注入:

通常javabean的属性都是私有的,同时拥有一组存取器方法,以setXXX和getXXX形式存在.spring可以借助属性的set方法来配置属性的值,以实现setter方法注入。

简单说明:

2.2.1 注入简单值的方式:

<bean id="kenny"
class="com.springinaction.springidol.Instrumentalist">
<property name="song" value="Jingle Bells" />
</bean>

在spring配置文件中,一旦Instrumentalist被实例化,<peoperty>元素会指示Spring调用setSong方法将song属性的值设置为"Jingle Bells"。需要说明的是value值的类型不基于String类型,也可以是数值类型和boolean类型,spring会根据属性值的类型进行自动转换。

2.2.2 通过Setter注入对象引用:

<bean id="kenny2"
class="com.springinaction.springidol.Instrumentalist">
<property name="song" value="Jingle Bells" />
<property name="instrument" ref="saxophone" />
</bean>

注入内部bean:

<bean id="kenny"
class="com.springinaction.springidol.Instrumentalist">
<property name="song" value="Jingle Bells" />
<property name="instrument">
<bean class="org.springinaction.springidol.Saxophone" />
</property>
</bean>

内部bean是通过直接声明一个<bean>元素作为<property>元素的子节点而定义的,内部bean并限于setter注入,还可以把内部bean装配到构造方法的入参中,如下所示:

<bean id="duke"
class="com.springinaction.springidol.PoeticJuggler">
<constructor-arg value="15" />
<constructor-arg>
<bean class="com.springinaction.springidol.Sonnet29" />
</constructor-arg>
</bean>

在这里,Sonnet29的一个实例将作为内部bean被创建,并作为参数传递给PoeticJuggler的构造器。

总结:需要注意的是内部Bean没有ID属性。虽然为内部bean配置一个ID属性是合法的,但是完全没有必要,因为永远不会通过名字来引用内部bean。这也突出了使用内部bean的最大缺点:它们不能被复用。内部bean仅适用于一次注入,而且也不能被其他bean所引用,而且某种程度上还会影响Spring XML配置的可读性。

3. 使用Spring的命名空间p装配属性

Spring的命名空间p提供了另外一种Bean属性的装配方式,命名空间的schema URI为

http://www.springframework.org/schema/p.如果想使用命名空间p,只需要在Spring的XML配置中增加如下一段声明:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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-3.0.xsd">

使用方式如下:

<bean id="kenny" class="com.springinaction.springidol.Instrumentalist"
p:song = "Jingle Bells"
p:instrument-ref = "saxophone" />

p:song属性的值被设置为"Jingle Bells",将使用该值装配bean属性。p:instrument-ref属性的值被设置为"saxophone",将使用一个ID为saxophone的Bean引用来装配instrument属性。-ref后缀作为一个标识来告诉Spring应该装配一个引用而不是字面值。

4. 装配集合元素

上面Spring的几种配置方式都只能配置简单属性值和引用其他bean的属性,当bean的属性值的类型是集合时只能使用集合的配置方式,Spring提供了四种类型的集合配置方式:

当装配类型为数值或者java.util.Collection任意实现的属性时,<List>和<Set>元素都可以用,其实属性实际定义的集合类型与选择<List>和<Set>没有任何关系。如果属性为任意的java.util.Collection类型时,这两个配置元素在使用时安全可以互换,不能因为属性为java.util.Set类型,就表示必须使用<set>元素来完成装配。使用<set>元素配置java.util.List类型的属性是可以的,只需要确保List中的每一个成员都必须是唯一的。

<map>和<props>这两个元素分别对应java.util.Map和java.util.Properties。当需要由键-值对组成的集合时,这两种配置元素非常有用,这两种配置元素的关键区别在于,<props>要求键和值都必须为String类型,而<map>允许键和值可以是任意类型。

4.1 装配集合元素之装配List,Set和Array

Java对instruments的声明如下:

private Collection<Instrument> instruments;

spring的配置文件配置如下:

<bean id="hank"
class="com.springinaction.springidol.OneManBand">
<property name="instruments">
<list>
<ref bean="guitar" />
<ref bean="cymbal" />
<ref bean="harmonica" />
</list>
</property>
</bean>

<list>元素包含一个或多个值。<ref>元素用来定义Spring上下文中的其他bean的引用。当然还可以使用其他的Spring设置元素作为<list>的成员,包括<value>,<bean>和<null/>,实际上<list>还可以包含另外一个<list>作为其成员,形成多维列表。

即使像下面的方式来配置instruments属性,<list>元素也一样有效:

java.util.List<Instrument> instruments;或者Instrument[] instruments;

同样有可以使用<set>元素来装配集合类型或者数组类型的属性:

<bean id="hank"
class="com.springinaction.springidol.OneManBand">
<property name="instruments">
<set>
<ref bean="guitar" />
<ref bean="cymbal" />
<ref bean="harmonica" />
<ref bean="harmonica" />
</set>
</property>
</bean>

4.2 装配集合元素之装配Map集合

Java对instruments的声明如下:

private Map<String, Instrument> instruments;

spring的配置文件配置如下:

<bean id="hank" class="com.springinaction.springidol.OneManBand">
<property name="instruments">
<map>
<entry key="GUITAR" value-ref="guitar" />
<entry key="CYMBAL" value-ref="cymbal" />
<entry key="HARMONICA" value-ref="harmonica" />
</map>
</property>
</bean>

<map>元素声明了一个java.util.Map类型的值。每个<entry>元素定义Map的一个成员。key元素指定了entry的键,而value-ref属性定义了entry的值,并引用了spring上下文中的其他bean。<entry>元素还有两个属性分别可以用来指定entry的键和值。

当键和值都不是String类型时,将键-值对注入到Bean属性的唯一方法就是使用<map>元素。

4.3 装配集合元素之装配Properties集合

如果所配置的Map的每一个entry的键和值都为String类型时,可以考虑使用java.util.Properties代替Map。Properties类提供了和Map大致相同的功能,但是它限定键和值必须是String类型。

Java对instruments的声明如下:

private Properties instruments;

spring的配置文件配置如下:

<bean id="hank" class="com.springinaction.springidol.OneManBand">
<property name="instruments">
<props>
<prop key="GUITAR">STRUM STRUM STRUM</prop>
<prop key="CYMBAL">CRASH CRASH CRASH</prop>
<prop key="HARMONICA">HUM HUM HUM</prop>
</props>
</property>
</bean>

Properties集合的配置要点:<property>元素用于把值或Bean引用注入到Bean的属性中;<props>元素用于定义一个java.util.Properties类型的集合值;<prop>元素用于定义<props>集合的一个成员。

4.4 装配空值

如果需要把属性值设置为null值,那么可以显示的为该属性装配一个null值。显示的为属性装配null值将会覆盖自动装配的值。

<property name="someNonNullProperty"><null/></property>

spring实战一:装配bean之注入Bean属性的更多相关文章

  1. Spring的自动装配与依赖注入

    Spring的自动装配与依赖注入 装配 = 创建Bean + 注入Bean 创建Bean 自动发现 显式注册Bean 注入Bean 基于配置的注入 自动注入 Spring的装配分为显式装配和隐式装配, ...

  2. 解决 spring boot 线程中使用@Autowired注入Bean的方法,报java.lang.NullPointerException异常

    问题描述 在开发中,因某些业务逻辑执行时间太长,我们常使用线程来实现.常规服务实现类中,使用 @Autowired 来注入Bean,来调用其中的方法.但如果在线程类中使用@Autowired注入的Be ...

  3. Spring入门之二-------SpringIoC之实例化Bean以及注入Bean

    一.实例化Bean 1. 通过默认构造方法实创建Bean public class Bean1 { public Bean1() { System.out.println(this.getClass( ...

  4. Spring(四)使用注解注入Bean

    注解简单介绍 是代码里面的特殊标记,使用注解完成功能. 注解写法@ 注解名称(属性名=属性值). 注解可以作用在类.方法.属性上面. 使用流程: 在ApplicationContext.xml中开启注 ...

  5. spring IOC bean中注入bean

    俩个实体 package com.java.test4; /** * @author nidegui * @create 2019-06-22 14:45 */ public class People ...

  6. Spring之使用注解实例化Bean并注入属性

    1.准备工作 (1)导入jar包 除了上篇文章使用到的基本jar包外,还得加入aop的jar包,所有jar包如下 所需jar包 (2)配置xml <?xml version="1.0& ...

  7. Spring学习(二)--装配Bean

    一.Spring装配机制 Spring提供了三种主要的装配机制: 1.在XML中进行显示配置 2.在Java中进行显示配置 3.隐式的bean发现机制和自动装配--自动化装配bean Spring可以 ...

  8. Spring读书笔记-----Spring的Bean之设置Bean值

    [java] view plaincopyprint? Java实例的属性值可以有很多种数据类型.基本类型值.字符串类型.java实例甚至其他的Bean实例.java集合.数组等.所以Spring允许 ...

  9. Spring 以及 Spring MVC Bean元素以及@Bean (Bean 等价于 注解 ??? 没理解错误吧)

    ①.由衷鸣谢Bossen <还是没看懂o(╥﹏╥)o><> {声明Spring Bean和注入Bean的几种常用注解和区别} Bean在Spring和SpringMVC中无所不 ...

随机推荐

  1. 整理的dedecms标签大全,方便查找

    平时用dedecms开发经常会用到一些标签,特别是首页.栏目页.内容页,这些页面都会用到标签的调用,比如title.keywords.description.arclist.field.body等,为 ...

  2. 给WordPress Page页面添加摘要输入框

    默认情况下 WordPress Page 编辑页面没有摘要(Excerpt)输入框,所以对 WordPress 进行 SEO 的时候比较麻烦. 这个时候我们就可以通过以下代码给我 WordPress ...

  3. python4delphi Python could not be properly initialized. We must quit.

    要用32位的DLL,不要用64位的dll Unable to load Python 2.7 dll with Delphi 2010 #6  Closed GoogleCodeExporter op ...

  4. HDU 4435 charge-station () bfs图论问题

    E - charge-station Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...

  5. 发个题目坑 二模03day1

    1.数列(seq2.pas/c/cpp) 题目描述 一个数列定义如下:f(1) = 1,f(2) = 1,f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.给定 A ...

  6. grep与egrep

    当只有一个匹配条件时:egrep pattern file等价于grep -E pattern file 例如: 当多个匹配条件时,只能用egrep -e pattern1 -e pattern2 - ...

  7. ImageMagick资料

    ImageMagick资料 ---------------------------------------------------------------------------- ImageMagi ...

  8. Linux下crontab命令的用法

    cron来源于希腊单词chronos(意为“时间”),是linux系统下一个自动执行指定任务的程序.例如,你想在每晚睡觉期间创建某些文件或文件夹的备份,就可以用cron来自动执行. 服务的启动和停止 ...

  9. spring事物传播属性

    PROPAGATION_REQUIRED Support a current transaction; create a new one if none exists.  支持一个当前事务;如果不存在 ...

  10. echart所有汉字都显示中文,就echarts的toolbox注释显示乱码

    echarts无所谓支不支持gbk编码这么一说,关键是页面的charset和echarts.js文件的charset是否匹配,如果不匹配,请使用如下方式引入: <script src=" ...