zoukankan      html  css  js  c++  java
  • spring 通过XML配置装配Bean

    装配Bean概述

      如何将自己开发的Bean装配到Spring IoC容器中。在大部分场景下,我们都会使用ApplicationContext的具体实现类,因为对应的Spring IoC容器功能相对强大。而在Spring中提供了3种方法进行配置:
      •在XML中显示配置。
      •在Java的接口和类中实现配置。
      •隐式Bean的发现机制和自动装配原则。

      在现实的工作中,这3种方式都会被用到,并且在学习和工作中常常混合使用,需要明确3种方式的优先级,也就是我们应该怎么选择使用哪种方式去把Bean发布到Spring IoC容器中。以下是的建议:
      (1)基于约定优于配置的原则,最优先的应该是通过隐式Bean的发现机制和自动装配的原则。这样的好处是减少程序开发者的决定权,简单又不失灵活。
      (2)在没有办法使用自动装配原则的情况下应该优先考虑Java接口和类中实现配置,这样的好处是避免XML配置的泛滥,也更为容易。这种场景典型的例子是一个父类有多个子类,比如学生类有两个子类:男学生类和女学生类,通过IoC容器初始化一个学生类,容器将无法知道使用哪个子类去初始化,这个时候可以使用Java的注解配置去指定。
      (3)在上述方法都无法使用的情况下,那么只能选择XML去配置Spring IoC容器。由于现实工作中常常用到第三方的类库,有些类并不是我们开发的,我们无法修改里面的代码,这个时候就通过XML的方式配置使用了。
      通俗来讲,当配置的类是你自身正在开发的工程,那么应该考虑Java配置为主,而Java配置又分为自动装配和Bean名称配置。在没有歧义的基础上,优先使用自动装配,这样就可以减少大量的XML配置。如果所需配置的类并不是你的工程开发的,那么建议使用XML的方式。

    通过XML配置装配Bean

      使用XML装配Bean需要定义对应的XML,这里需要引入对应的XML模式(XSD)文件,这些文件会定义配置SpringBean的一些元素,一个简单的配置如下:

    <?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-4.0.xsd">     
        <!--Spring Bean配置代码--> 
    </beans>

      在上述代码中引入了一个beans的定义,它是一个根元素,而XSD文件也被引入了,这样它所定义的元素将可以定义对应的Spring Bean。

    装配简易值

      代码清单:简易XML装配bean

    <bean id="role2" class="com.ssm.chapter9.pojo.Role">
        <property name="id" value="1"/>
        <property name="roleName" value="高级工程师"/>
        <property name="note" value="重要人员"/>
    </bean>

      这是一个简易的配置,简单解释一下:
      •id属性是Spring找到的这个Bean的编号,不过id不是一个必需的属性,如果没有声明它,那么Spring将会采用“全限定名#{number}”的格式生成编号。如果只声明一个这样的类,而没有声明id="role2",那么Spring为其生成的编号就是“com.ssm.chapter9.pojo.Role#0”。当它第二次声明没有id属性的Bean时,编号就是“com.ssm.chap-ter9.pojo.Role#1”,但是一般我们都会选择自己定义id,因为自动生成的id会比较烦琐。
      •class显然是一个类全限定名。
      •property元素是定义类的属性,其中name属性定义的是属性名称,而value是其值。

      这样的定义很简单,但是有时候需要注入一些自定义的类,比如之前的果汁制造器例子,它需要原料信息和饮品店共同完成,于是可能要先定义原料的信息,然后在制造器中引用原料,如代码清单所示。

    <bean id="source" class="com.ssm.chapter9.pojo.Source">
        <property name="fruit" value="橙汁"/>
        <property name="sugar" value="少糖"/>
        <property name="size" value="3"/>
    </bean>
    
    <bean id="juiceMaker2" class="com.ssm.chapter9.pojo.JuiceMaker2">
        <property name="beverageShop" value="贡茶"/>
        <property name="source" ref="source"/>
    </bean>

      这里先定义了一个id为source的Bean,然后在制造器中通过ref属性去引用对应的Bean,而source正是之前定义的Bean的id,这样就可以相互引用了。

    装配集合

      有些时候要做一些复杂的装配工作,比如Set、Map、List、Array和Properties等。为了介绍它们,先定义个Bean,如代码清单所示。

    public class ComplexAssembly {
    
        private Long id;
        private List<String> list;
        private Map<String, String> map;
        private Properties props;
        private Set<String> set;
        private String[] array;
    
        /****setter and getter ****/
    
    }

      这个Bean没有任何的业务含义,只是为了介绍如何装配这些常用的集合类,为此可以如同代码清单10-9这样装配这些属性。

    代码清单:装配集合类spring-cfg.xml

    <bean id="complexAssembly" class="com.ssm.chapter10.pojo.ComplexAssembly">
            <property name="id" value="1"/>
            <property name="list">
                <list>
                    <value>value-list-1</value>
                    <value>value-list-2</value>
                    <value>value-list-3</value>
                </list>
            </property>
            <property name="map">
                <map>
                    <entry key="key1" value="value-key-1"/>
                    <entry key="key2" value="value-key-2"/>
                    <entry key="key3" value="value-key-3"/>
                </map>
            </property>
            <property name="props">
                <props>
                    <prop key="prop1">value-prop-1</prop>
                    <prop key="prop2">value-prop-2</prop>
                    <prop key="prop3">value-prop-3</prop>
                </props>
            </property>
            <property name="set">
                <set>
                    <value>value-set-1</value>
                    <value>value-set-2</value>
                    <value>value-set-3</value>
                </set>
            </property>
            <property name="array">
                <array>
                    <value>value-array-1</value>
                    <value>value-array-2</value>
                    <value>value-array-3</value>
                </array>
            </property>
        </bean>

      当然这里的装配主要集中在比较简单的String类型上,其主要的目的是告诉大家如何装配一些简易的数据到集合中。
      •List属性为对应的<list>元素进行装配,然后通过多个<value>元素设值。
      •Map属性为对应的<mali>元素进行装配,然后通过多个<entry>元素设值,只是entry包含一个键(key)和一个值(value)的设置。
      •Properties属性,为对应的<properties>元素进行装配,通过多个<property>元素设置,只是property元素有一个必填属性key,然后可以设置值。
      •Set属性为对应的<set>元素进行装配,然后通过多个<value>元素设值。
      •对于数组而言,可以使用<array>设置值,然后通过多个<value>元素设值。

    ApplicationContext ctx = new ClassPathXmlApplicationContext("ssm/chapter10/spring-cfg.xml");
    ComplexAssembly userRoleAssembly = (ComplexAssembly) ctx.getBean("userRoleAssembly");
    System.out.println(userRoleAssembly.toString());

      从上面可以看到对字符串的各个集合的装载,但是有些时候可能需要更为复杂的装载,比如一个List可以是一个系列类的对象,又如一个Map集合类,键可以是一个类对象,而值也要是一个类对象,这些也是Java中常常可以看到的。

    public class Role {
        private Long id;
        private String roleName;
        private String note;
    }
    public class User {
        private Long id;
        private String userName;
        private String note;
    }
    public class UserRoleAssembly {
        private Long id;
        private List<Role> list;
        private Map<Role, User> map;
        private Set<Role> set;
    }

      spring-cfg2.xml:

        <bean id="role1" class="com.ssm.chapter10.pojo.Role">
            <property name="id" value="1"/>
            <property name="roleName" value="role_name_1"/>
            <property name="note" value="role_note_1"/>
        </bean>
        <bean id="role2" class="com.ssm.chapter10.pojo.Role">
            <property name="id" value="2"/>
            <property name="roleName" value="role_name_2"/>
            <property name="note" value="role_note_2"/>
        </bean>
        <bean id="user1" class="com.ssm.chapter10.pojo.User">
            <property name="id" value="1"/>
            <property name="userName" value="user_name_1"/>
            <property name="note" value="role_note_1"/>
        </bean>
        <bean id="user2" class="com.ssm.chapter10.pojo.User">
            <property name="id" value="2"/>
            <property name="userName" value="user_name_2"/>
            <property name="note" value="role_note_1"/>
        </bean>
        <bean id="userRoleAssembly" class="com.ssm.chapter10.pojo.UserRoleAssembly">
            <property name="id" value="1"/>
            <property name="list">
                <list>
                    <ref bean="role1"/>
                    <ref bean="role2"/>
                </list>
            </property>
            <property name="map">
                <map>
                    <entry key-ref="role1" value-ref="user1"/>
                    <entry key-ref="role2" value-ref="user2"/>
                </map>
            </property>
            <property name="set">
                <set>
                    <ref bean="role1"/>
                    <ref bean="role2"/>
                </set>
            </property>
        </bean>
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("ssm/chapter10/spring-cfg2.xml");
    UserRoleAssembly userRoleAssembly = (UserRoleAssembly) ctx.getBean("userRoleAssembly");
    System.out.println(userRoleAssembly.toString());

    命名空间装配

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

        <bean id="role1" class="com.ssm.chapter10.pojo.Role" c:_0="1" c:_1="role_name_1" c:_2="role_note_1"/>
        <bean id="role2" class="com.ssm.chapter10.pojo.Role" p:id="2" p:roleName="role_name_2" p:note="role_note_2"/>
        <bean id="user1" class="com.ssm.chapter10.pojo.User" p:id="1" p:userName="role_name_1" p:note="user_note_1"/>
        <bean id="user2" class="com.ssm.chapter10.pojo.User" p:id="2" p:userName="role_name_2" p:note="user_note_2"/>
        <util:list id="list">
            <ref bean="role1"/>
            <ref bean="role2"/>
        </util:list>
        <util:map id="map">
            <entry key-ref="role1" value-ref="user1"/>
            <entry key-ref="role2" value-ref="user2"/>
        </util:map>
        <util:set id="set">
            <ref bean="role1"/>
            <ref bean="role2"/>
        </util:set>
        <bean id="userRoleAssembly" class="com.ssm.chapter10.pojo.UserRoleAssembly" p:id="1" p:list-ref="list" p:map-ref="map" p:set-ref="set"/>
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("ssm/chapter10/spring-cfg3.xml");
    UserRoleAssembly userRoleAssembly = (UserRoleAssembly) ctx.getBean("userRoleAssembly");
    System.out.println(userRoleAssembly.toString());
  • 相关阅读:
    用 Python 带你看各国 GDP 变迁
    Fluent Interface(流式接口)
    probing privatePath如何作用于ASP.NET MVC View
    Word插入htm文件导致文本域动态增加的一个问题
    Visual Studio 2013附加进程调试IE加载的ActiveX Control无效解决方法
    Ubuntu下Chrome运行Silverlight程序
    Windows Phone Bing lock screen doesn't change解决方法
    SPClaimsUtility.AuthenticateFormsUser的证书验证问题
    Web Service Client使用Microsoft WSE 2.0
    Visual Studio 2013安装Update 3启动crash的解决方法
  • 原文地址:https://www.cnblogs.com/ooo0/p/10962403.html
Copyright © 2011-2022 走看看