zoukankan      html  css  js  c++  java
  • Spring Bean装配

    使用 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。

    要查看Spring可配置的命名空间,可以下载Spring的dist查看。

    下载地址:http://repo.springsource.org/libs-release-local/ , 这是一个树结构。

    直接地址:https://repo.spring.io/libs-release-local/org/springframework/spring/5.1.16.RELEASE/

     装配简单值
    <bean id="c" class="pojo.Category">
        <property name="name" value="测试" />
    </bean>

    简单解释下:

    • id 属性是 Spring 能找到当前 Bean 的一个依赖的编号,遵守 XML 语法的 ID 唯一性约束。必须以字母开头,可以使用字母、数字、连字符、下划线、句号、冒号,不能以 / 开头。不过 id 属性不是一个必需的属性name 属性也可以定义 bean 元素的名称,能以逗号或空格隔开起多个别名,并且可以使用很多的特殊字符,比如在 Spring 和 Spring MVC 的整合中,就得使用 name 属性来定义 bean 的名称,并且使用 / 开头。注意: 从 Spring 3.1 开始,id 属性也可以是 String 类型了,也就是说 id 属性也可以使用 / 开头,而 bean 元素的 id 的唯一性由容器负责检查。如果 id 和 name 属性都没有声明的话,那么 Spring 将会采用 “全限定名#{number}” 的格式生成编号。 例如这里,如果没有声明 “id="c"” 的话,那么 Spring 为其生成的编号就是 “pojo.Category#0”,当它第二次声明没有 id 属性的 Bean 时,编号就是 “pojo.Category#1”,以此类推。
    • class 属性显然就是一个类的全限定名
    • property 元素是定义类的属性,其中的 name 属性定义的是属性的名称,而 value 是它的值。

     这样的定义很简单,但是有时候需要注入一些自定义的类:

    <!-- 配置 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 属性
     装配集合

     有些时候我们需要装配一些复杂的东西,比如 Set、Map、List、Array 和 Properties 等

    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>
    命名空间装配

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

    【① c-命名空间】

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

     

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

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

    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-命名空间】

     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:list> 只是 util-命名空间中的多个元素之一,下表提供了 util-命名空间提供的所有元素:

    元素描述
    <util:constant> 引用某个类型的 public static 域,并将其暴露为 bean
    <util:list> 创建一个 java.util.List 类型的 bean,其中包含值或引用
    <util:map> 创建一个 java.util.map 类型的 bean,其中包含值或引用
    <util:properties> 创建一个 java.util.Properties 类型的 bean
    <util:property-path> 引用一个 bean 的属性(或内嵌属性),并将其暴露为 bean
    <util:set> 创建一个 java.util.Set 类型的 bean,其中包含值或引用
    引入其他配置文件

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

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

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

    2. 在 applicationContext.xml 文件中写入:

    <import resource="bean.xml" />

    参考

    https://www.cnblogs.com/wmyskxz/p/8830632.html

  • 相关阅读:
    [译]Java例解Interface
    【笔记】2014-01至2014-02
    【笔记】2013-12
    【笔记】2013-10至2013-11
    【笔记】2013-09
    【笔记】2013-08
    【笔记】2013-07
    生活工作中好用的快捷键和小工具(更新)
    Android Studio更新Gradle问题
    gradle构建spring5源码
  • 原文地址:https://www.cnblogs.com/myitnews/p/13278665.html
Copyright © 2011-2022 走看看