文档章节

Spring4-容器5-依赖配置详解

王胜_淡如止水
 王胜_淡如止水
发布于 2017/03/24 22:17
字数 2321
阅读 18
收藏 1

1 直接变量 (基本类型, String类型等)

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <!-- results in a setDriverClassName(String) call -->
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
    <property name="username" value="root"/>
    <property name="password" value="masterkaoli"/>
</bean>

2 idref元素

idref元素用来将容器内其他bean的id(值是字符串-不是引用)传给元素<constructor-arg/> 或者 <property/>

<bean id="theTargetBean" class="..."/>

<bean id="theClientBean" class="...">
    <property name="targetName">
        <idref bean="theTargetBean" />
    </property>
</bean>

    上面的bean定义片段完全等同于(在运行时)下面片段:

<bean id="theTargetBean" class="..." />

<bean id="client" class="...">
    <property name="targetName" value="theTargetBean" />
</bean>

    第一种形式比第二种形式更好,因为使用idref标签允许容器在部署时验证引用的bean是否存在。 在第二种形式中,传给 client bean中属性targetName的值并没有被验证。 只有当 client bean完全实例化的时候错误才会被发现(可能伴随着致命的结果)。如果 client bean是原型 bean。那么这个错误和异常可能只有再容器部署很长一段时间后才能被发现。

    与ProxyFactoryBean bean定义中使用<idref/>元素指定AOP 拦截器配置 (版本不低于Spring 2.0)相同之处在于:当你指定拦截器名称的时候使用<idref/>元素可以防止你拼错拦截器的id。

3 引用其他bean

    在 <constructor-arg/> 或者 <property/>可以使用ref 元素。该元素用来将bean中指定属性的值设置为对容器的另外一个bean的引用。该引用bean将被作为依赖注入,而且再注入之前会被初始化(如果协作者是单例)。xml的bean元素的值既可以目标bean的id属性也可以是其中一个目标bean的name 属性值。

<ref bean="someBean"/>

4 使用parent属性引用父容器中的同名Bean

    通过parent属性指定目标bean来创建bean的引用,该bean是当前容器下的父级容器。parent属性值既可以是目标bean的id也可以是 name属性值。而且目标bean必须在当前容器的父级容器中。使用parent属性的主要用途是为了用某个与父级容器中的bean同名的代理来包装父级容器中的一个bean。

<!-- in the parent context -->
<bean id="accountService" class="com.foo.SimpleAccountService">
    <!-- insert dependencies as required as here -->
</bean>
<!-- in the child (descendant) context -->
<bean id="accountService" <!-- bean name is the same as the parent bean -->
    class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target">
        <ref parent="accountService"/> <!-- notice how we refer to the parent bean -->
    </property>
    <!-- insert other configuration and dependencies as required here -->
</bean>

4 内部bean

    所谓的内部bean就是指在 <property/> 或者 <constructor-arg/> 元素内部使用<bean/>定义bean。

<bean id="outer" class="...">
    <!-- instead of using a reference to a target bean, simply define the target bean inline -->
    <property name="target">
        <bean class="com.example.Person"> <!-- this is the inner bean -->
            <property name="name" value="Fiona Apple"/>
            <property name="age" value="25"/>
        </bean>
    </property>
</bean>

    内部bean的定义不需要id或者name属性。容器会忽略这些属性值。同时容器也会忽略scope标志位。内部bean 总是 匿名的 并且他们总是伴随着外部bean创建。同时将内部bean注入到包含该内部bean之外的bean是不可能的。

5 集合

    在<list/><set/><map/>, 和<props/>元素中,你可以设置值和参数分别对应Java的集合类型ListSetMap, 和 Properties

<bean id="moreComplexObject" class="example.ComplexObject">
    <!-- results in a setAdminEmails(java.util.Properties) call -->
    <property name="adminEmails">
        <props>
            <prop key="administrator">administrator@example.org</prop>
            <prop key="support">support@example.org</prop>
            <prop key="development">development@example.org</prop>
        </props>
    </property>
    <!-- results in a setSomeList(java.util.List) call -->
    <property name="someList">
        <list>
            <value>a list element followed by a reference</value>
            <ref bean="myDataSource" />
        </list>
    </property>
    <!-- results in a setSomeMap(java.util.Map) call -->
    <property name="someMap">
        <map>
            <entry key="an entry" value="just some string"/>
            <entry key ="a ref" value-ref="myDataSource"/>
        </map>
    </property>
    <!-- results in a setSomeSet(java.util.Set) call -->
    <property name="someSet">
        <set>
            <value>just some string</value>
            <ref bean="myDataSource" />
        </set>
    </property>
</bean>

map的key或者value值,或者set的value值还可以是以下任意元素:

bean | ref | idref | list | set | map | props | value | null

6 集合合并

    Spring元素支持父子Bean的集合的合并,子集中的元素值将覆盖父集中对应的值。

<beans>
    <bean id="parent" abstract="true" class="example.ComplexObject">
        <property name="adminEmails">
            <props>
                <prop key="administrator">administrator@example.com</prop>
                <prop key="support">support@example.com</prop>
            </props>
        </property>
    </bean>
    <bean id="child" parent="parent">
        <property name="adminEmails">
            <!-- the merge is specified on the child collection definition -->
            <props merge="true">
                <prop key="sales">sales@example.com</prop>
                <prop key="support">support@example.co.uk</prop>
            </props>
        </property>
    </bean>
<beans>

注意child`bean的定义中<props/>元素上的`merge=true属性的是表示需要集合合并。

上述的合并结果为:

administrator=administrator@example.com
sales=sales@example.com
support=support@example.co.uk

<list/><map/>, 和 <set/>集合类型的合并处理都基本类似。<list/>元素某个方面有点特殊,这和List集合类型的语义学有关 换句话说,比如维护一个有序集合的值,父bean的列表内容将排在子bean李彪内容的前面。

7 强类型集合

    Java 5 引入了泛型,这样你可以使用强类型集合。换句话说声明一个只能包含String类型元素的Collection ,如果使用Spring来给bean注入强类型的Collection,在向强类型Collection添加元素前,这些元素将被转换成String类型的。

public class Foo {

    private Map<String, Float> accounts;

    public void setAccounts(Map<String, Float> accounts) {
        this.accounts = accounts;
    }
}
<beans>
    <bean id="foo" class="x.y.Foo">
        <property name="accounts">
            <map>
                <entry key="one" value="9.99"/>
                <entry key="two" value="2.75"/>
                <entry key="six" value="3.99"/>
            </map>
        </property>
    </bean>
</beans>

foo bean的accounts 属性准备注入时,通过反射获得强类型Map<String, Float>元素类型的泛型信息。Spring的底层类型转换 机制会把各种value元素值转换为Float,因此字符串9.99, 2.75 和3.99将会转换为实际的Float 类型。

8 Null和空字符串

Spring会把空属性当做空字符串处理。以下的基于XML配置的片段将email属性设置为空字符串。

<bean class="ExampleBean">
    <property name="email" value=""/>
</bean>

先前的例子等同于以下Java代码:

exampleBean.setEmail("")

<null/>元素处理null值,例如:

<bean class="ExampleBean">
    <property name="email">
        <null/>
    </property>
</bean>

上面的配置等同于下面的Java代码:

exampleBean.setEmail(null)

9 XML使用p命名空间简化

    p命名空间不是定义在XSD文件而是存在于Spring内核中,不需要在XSD schema中定义。

    下面的例子展示了两种XML片段,其结果是一样的:第一个使用了标准XML格式,第二种使用了p命名空间。

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="classic" class="com.example.ExampleBean">
        <property name="email" value="foo@bar.com"/>
    </bean>

    <bean name="p-namespace" class="com.example.ExampleBean"
        p:email="foo@bar.com"/>
</beans>

接下来的例子包括了两种以上bean的定义,都引用了另外一个bean。

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="john-classic" class="com.example.Person">
        <property name="name" value="John Doe"/>
        <property name="spouse" ref="jane"/>
    </bean>

    <bean name="john-modern"
        class="com.example.Person"
        p:name="John Doe"
        p:spouse-ref="jane"/>

    <bean name="jane" class="com.example.Person">
        <property name="name" value="Jane Doe"/>
    </bean>
</beans>

    正如你看到的,例子不仅使用p命名空间包含了一个属性值,而且使用了一个特殊的格式声明了一个属性的引用。在第一个bean 定义中使用了<property name="spouse" ref="jane"/>创建一个john bean 对jane bean的引用,第二个bean的定义使用了p:spouse-ref="jane",它们做了同样一件事情。在这个例子中spouse是属性名,而-ref部分声明了这不是一个直接的值而是另一个bean的引用。

    p命名空间没有标准XML格式那么灵活。举个例子,声明属性的引用是以Ref结尾的,采用p命名空间将会产生冲突,但是采用标准XML 格式则不会。我们建议你小心的选择并和团队成员交流你的想法,避免在XML文档中同时使用所有的三种方法。

10 c命名空间

c命名空间不是定义在XSD文件而是存在于Spring内核中,不需要在XSD schema中定义。

下面是一个使用C命名空间的例子

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:c="http://www.springframework.org/schema/c"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="bar" class="x.y.Bar"/>
    <bean id="baz" class="x.y.Baz"/>

    <!-- traditional declaration -->
    <bean id="foo" class="x.y.Foo">
        <constructor-arg ref="bar"/>
        <constructor-arg ref="baz"/>
        <constructor-arg value="foo@bar.com"/>
    </bean>

    <!-- c-namespace declaration -->
    <bean id="foo" class="x.y.Foo" c:bar-ref="bar" c:baz-ref="baz" c:email="foo@bar.com"/>

</beans>

    极少数的情况下构造器参数的名称不可用(通常字节码没有经过调试信息编译),可以使用备份进行参数索引。

<!-- c-namespace index declaration -->
<bean id="foo" class="x.y.Foo" c:_0-ref="bar" c:_1-ref="baz"/>

    因为XML的语法,索引标记需要_主导作为XML属性名称,这不能已数字开头(即使某些IDE这么允许)

11 组合属性名称

    当你设置bean属性时可以使用组合或者嵌套属性名称,只要路径上所有组件除了最终属性不为空。看以下bean的定义:

<bean id="foo" class="foo.Bar">
    <property name="fred.bob.sammy" value="123" />
</bean>

foo bean有一个fred属性,fred属性又有个bob属性,bob属性又有个属性,最后把 sammy属性设置值为123。为了是这个起作用,foofred属性和 fredbob属性在bean被构造后都不能为空,否则会抛出NullPointerException异常。

© 著作权归作者所有

王胜_淡如止水
粉丝 4
博文 52
码字总数 81235
作品 0
杭州
私信 提问
spring核心框架体系结构

在普通java工程使用spring框架,需要哪些jar呢?只要一个: 那要在web工程中引入spring mvc呢?也只要配置一个依赖: 为什么可以这样配置?接下来我们以spring 3.2.17.RELEASE版本为例,介绍...

心梦无双
2016/12/24
98
0
5分钟构建spring web mvc REST风格HelloWorld

当然写本文的目的不是为了速度,只是表明现在构建一个Spring web mvc Rest风格的HelloWorld应用会很简单。不过如果看过Spring Boot这个项目,可能只需要最多3分钟就能构建一个简单的Rest风格...

黄金小猪2号
2014/01/07
4.3K
2
spring核心框架体系结构

很多人都在用spring开发java项目,但是配置maven依赖的时候并不能明确要配置哪些spring的jar,经常是胡乱添加一堆,编译或运行报错就继续配置jar依赖,导致spring依赖混乱,甚至下一次创建相...

haoran_10
2016/12/22
41
0
Spring4新特性——泛型限定式依赖注入

Spring4新特性——泛型限定式依赖注入 Spring4新特性——核心容器的其他改进 Spring4新特性——Web开发的增强 Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC Spring4新特性...

Big_BoBo
2013/12/26
449
0
Eclipse搭建Maven工程集成Spring4+Hibernate5

版权声明:http://blog.csdn.net/anxpp https://blog.csdn.net/anxpp/article/details/50600034 Eclipse搭建Maven工程集成Spring4+Hibernate5 这里将以Eclipse搭建Maven工程集成Spring4生成的......

anxpp
2016/01/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

读书笔记:深入理解ES6 (五)

第五章 解构:使数据访问更便捷 第1节 为什么使用解构功能?   在ES5中,开发者们从对象、数组中获取特定数据并赋值给变量,编写了很多看起来同质化的代码。例如: 1 let options = {2 ...

张森ZS
19分钟前
18
0
CentOS7 yum方式安装MySQL5.7

在CentOS中默认安装有MariaDB,这个是MySQL的分支,但为了需要,还是要在系统中安装MySQL,而且安装完成之后可以直接覆盖掉MariaDB。 1 下载并安装MySQL官方的 Yum Repository [root@localho...

roockee
28分钟前
14
0
Allegro三种自定义设置快捷键的方法

Allegro自定义设置快捷键的三种方法: 1、在Allegro PCB editor 命令窗口直接定义 2、通过修改用户变量env文件来设置快捷键 3、定义笔画为快捷键 1、在Allegro PCB editor 命令窗口直接定义 ...

demyar
32分钟前
15
0
如何做一张能让人眼前一亮的大屏?

作为在职场驰骋的社会人,提到数据可视化大家应该都不陌生了。数据可视化的作用也不用我多说,主要是利用图形化手段,更清晰直观地将数据展示。多层次、交互式的可视化分析能够方便决策者理解...

朕想上头条
33分钟前
8
0
TL138/1808/6748-EthEVM开发板硬件CPU、FLASH、RAM

TL138/1808/6748-EthEVM是广州创龙基于SOM-TL138/1808/6748核心板开发的一款开发板,具有三个网络接口。由于SOM-TL138/1808/6748核心板管脚兼容,所以此三个核心板共用同一个底板。开发板采用...

Tronlong创龙
37分钟前
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部