• 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());
  • 相关阅读:
    Solution -「洛谷 P5659」「CSP-S 2019」树上的数
    前端随心记---------接私活必备的 10 个开源项目!
    前端随心记---------Vue3.0马上就要来了,TypeScript学会了没?
    前端随心记---------vue3.0终于来了,作者已公布源码
    前端随心记---------vuex
    前端随心记---------为什么要使用Nodejs
    前端随心记---------Javascript系列(第三节.函数的变量提升)
    前端随心记---------Javascript系列(第二节----函数.事件处理程序)
    前端随心记---------Javascript系列(判断一个数是否为素数的三种解法)
    前端随心记---------Javascript系列(第一节)
  • 原文地址:https://www.cnblogs.com/ooo0/p/10962403.html
Copyright © 2020-2023  润新知