内容参考自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. 获取并设置ListView高度的方法

    01 public void setListViewHeightBasedOnChildren(ListView listView) {  02     ListAdapter listAdapter ...

  2. 不同版本的name可以重复

    - validates :name, presence: true, uniqueness: { conditions: -> { where(:state.ne => 2) } }, l ...

  3. myeclipse2014集成SVN

    团队合作的项目肯定少不了版本控制,那么现在就看看myeclispe中是如何使用的吧. 开发环境:myeclipse 2014   java 8 tomcate 8 试了网上说的几种方法,都没有成功,最 ...

  4. BNUOJ 1037 精神控制

    XsuagrX喜欢到处唬人,各种唬.这不,经过刻苦修炼,他终于掌握了Bane Element的Ultra绝技加强版,恶魔掌控(快捷键F)(YY中&……).当XsugarX对某个人胡言乱语Q@# ...

  5. Linux 查看系统用户的登录日志

    查看用户登录系统的日志   有两类日志记录用户登录的行为,一是记录登录者的数据,一个是记录用户的登录时间   一,记录用户登录数据         /var/log/wtmp日志文件记录用户登录的数据 ...

  6. HTML5/CSS3开发工具

    1.谷歌Google Web Designer https://www.google.com/webdesigner/ 这个工具不能在xp上运行,可以在win7 win8上运行 http://www. ...

  7. MAC的OS X10.10更新以后进入用户界面就死机

    我用的是搜狗输入法,所以把搜狗卸载就好了.(注意是卸载,不是单纯的从输入源里移除) 下载一个搜狗输入法的DMG,打开后选择卸载搜狗输入法. 转自: http://zhidao.baidu.com/qu ...

  8. 《转》VS2012发布网站详细步骤

    本文转载自MannyGuo 如果给您带来不便请联系博主 1.打开你的VS2012网站项目,右键点击项目>菜单中 重新生成一下网站项目:再次点击右键>发布: 2.弹出网站发布设置面板,点击& ...

  9. 【leetcode】Palindrome Partitioning II

    Palindrome Partitioning II Given a string s, partition s such that every substring of the partition ...

  10. swfit 中的类型属性说明

    swift 中不叫做类属性,叫类型属性,因为在swift中,struct 和enum也是可以有这种属性的,叫类属性明显不准. 有以下注意事项: 对于值类型(指结构体和枚举)可以定义存储型和计算型类型属 ...