Spring Bean 配置细节

引用其它 Bean

组成应用程序的 Bean 经常需要相互协作以完成应用程序的功能. 使 Bean 能够相互访问, 就必须在 Bean 配置文件中指定对 Bean 的引用

Bean 的配置文件中, 可以通过 <ref> 元素或 ref  属性Bean 的属性或构造器参数指定对 Bean 的引用.

如我们构造一个Person类

public class Person {

    private String name;
    private int age;

    private Car car;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", car=" + car +
                '}';
    }
}

在bean中通过ref建立bean之间的联系

<bean id="person" class="com.spring.Person">
    <property name="name" value="Tom"></property>
    <property name="age" value="24"></property>
    <!--可以使用property 的ref 属性建立bean之间的引用关系-->
    <property name="car" ref="car2"></property>
</bean>
Person person = (Person) ctx.getBean("person");
System.out.println(person);

调用该bean可以看到程序输出

Person{name='Tom', age=24, car=Car{brand='Baoma', corp='Tianjin', price=0.0, maxSpeed=200}}

也可以在属性或构造器里包含 Bean 的声明, 这样的 Bean 称为内部 Bean

<bean id="person" class="com.spring.Person">
        <property name="name" value="Tom"></property>
        <property name="age" value="24"></property>

        <!--可以使用property 的ref 属性建立bean之间的引用关系-->
        <!--<property name="car" ref="car2"></property>-->

        <!--使用内部bean-->
        <property name="car">
            <bean class="com.spring.Car">
                <constructor-arg value="Ford"></constructor-arg>
                <constructor-arg value="Changan"></constructor-arg>
                <constructor-arg value="200000"></constructor-arg>
            </bean>
        </property>

    </bean>

内部bean不能被外部引用,只能在内部使用

Bean 实例仅仅给一个特定的属性使用时, 可以将其声明为内部 Bean. 内部 Bean 声明直接包含在 <property> <constructor-arg> 元素里, 不需要设置任何 id name 属性

内部 Bean 不能使用在任何其他地方

注入参数详解null 值和级联属性

可以使用专用的 <null/> 元素标签为 Bean 的字符串或其它对象类型的属性注入 null

StrutsHiberante 等框架一样,Spring 支持级联属性的配置

扫描二维码关注公众号,回复: 4531836 查看本文章
<bean id="person2" class="com.spring.Person">
        <constructor-arg value="Jerry"></constructor-arg>
        <constructor-arg value="25"></constructor-arg>
        <!--<constructor-arg ref="car"></constructor-arg>-->
        <!--测试赋值null-->
        <constructor-arg><null></null></constructor-arg>
    </bean>

用该方法,此时给person2这个对象赋的car值为null

Person{name='Jerry', age=25, car=null}

集合属性

假设一个person拥有两辆车,我们现在构造一个Person类,其属性Car为list类型

package com.collection;

import java.util.List;

public class Person {

    private String name;
    private int age;

    private List<Car> cars;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<Car> getCars() {
        return cars;
    }

    public void setCars(List<Car> cars) {
        this.cars = cars;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", cars=" + cars +
                '}';
    }
}

更改配置文件

<!--测试如何配置集合属性-->
    <bean id="person3" class="com.collection.Person">
        <property name="name" value="Mike"></property>
        <property name="age" value="23"></property>
        <property name="cars">
            <list>
                <!--cars是一个集合类型-->
                <ref bean="car"></ref>
                <ref bean="car2"></ref>
            </list>
        </property>
    </bean>

注意:其中ref指向的bean,其car和car2必须和Person在同一个包下

运行

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) ctx.getBean("person3");
System.out.println(person);

我们看看运行结果

Person{name='Mike', age=23, cars=[Car{brand='Audi', corp='ShangHai', price=300000.0, maxSpeed=0}, Car{brand='Baoma', corp='Tianjin', price=0.0, maxSpeed=200}]}

Spring可以通过一组内置的 xml 标签(例如: <list>, <set> <map>) 来配置集合属性.

配置 java.util.List 类型的属性, 需要指定 <list>  标签, 在标签里包含一些元素. 这些标签可以通过 <value> 指定简单的常量值, 通过 <ref> 指定对其他 Bean 的引用或者可以通过构造方法注入,具体的如何通过构造方法注入可参考上篇博客. 通过<bean> 指定内置 Bean 定义. 通过 <null/> 指定空元素. 甚至可以内嵌其他集合.

数组的定义和 List 一样, 都使用 <list>

Java.util.Map

配置 java.util.Set 需要使用 <set> 标签, 定义元素的方法与 List 一样.

Java.util.Map 通过 <map> 标签定义, <map> 标签里可以使用多个 <entry> 作为子标签. 每个条目包含一个键和一个值.

必须在 <key> 标签里定义键

因为键和值的类型没有限制, 所以可以自由地为它们指定 <value>, <ref>, <bean> <null> 元素.

可以将 Map 的键和值作为 <entry> 的属性定义: 简单常量使用 key value 来定义; Bean 引用通过 key-ref value-ref 属性定义

package com.collection;


import java.util.Map;

public class NewPerson {

    private String name;
    private int age;

    private Map<String,Car> cars;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Map<String, Car> getCars() {
        return cars;
    }

    public void setCars(Map<String, Car> cars) {
        this.cars = cars;
    }

    @Override
    public String toString() {
        return "NewPerson{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", cars=" + cars +
                '}';
    }
}

我们再看看配置文件,使用map节点及map的entry子节点配置Map类型的成员变量

<bean id="newPerson" class="com.collection.NewPerson">
        <property name="name" value="Rose"></property>
        <property name="age" value="28"></property>
        <property name="cars">
            <map>
                <entry key="AA" value-ref="car"></entry>
                <entry key="BB" value-ref="car2"></entry>
            </map>
        </property>
    </bean>

看运行结果

NewPerson{name='Rose', age=28, cars={AA=Car{brand='Audi', corp='ShangHai', price=300000.0, maxSpeed=0}, BB=Car{brand='Baoma', corp='Tianjin', price=0.0, maxSpeed=200}}}

使用 <props> 定义 java.util.Properties, 该标签使用多个 <prop> 作为子标签. 每个 <prop> 标签必须定义 key 属性.

定义一个NewPerson类,其Car类型使用Map类型

新建Properties类

import java.util.Properties;

public class DataSource {

    private Properties properties;

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "DataSource{" +
                "properties=" + properties +
                '}';
    }
}

配置,使用props和prop子节点为Properties属性赋值

<!--配置Properties属性值-->
    <bean id="dataSource" class="com.collection.DataSource">
        <property name="properties">
            <props>
                <prop key="user">root</prop>
                <prop key="password">1234</prop>
                <prop key="jdbcUrl">jdbc:mysql://test</prop>
                <prop key="driverClass">com.mysql.jdbc.Driver</prop>
            </props>
        </property>
    </bean>

运行结果

DataSource{properties={driverClass=com.mysql.jdbc.Driver, user=root, password=1234, jdbcUrl=jdbc:mysql://test}}

如何将集合的配置拿出来,希望它也配置成一个Bean的方式

使用 utility scheme 定义集合

使用基本的集合标签定义集合时, 不能将集合作为独立的 Bean 定义, 导致其他 Bean 无法引用该集合, 所以无法在不同 Bean 之间共享集合.

可以使用 util schema 里的集合标签定义独立的集合 Bean. 需要注意的是, 必须在 <beans> 根元素里添加 util schema 定义

如配置文件写成

<!--配置单例的集合bean,以供多个bean引用-->
    <util:list id="cars">
        <ref bean="car"></ref>
        <ref bean="car2"></ref>
    </util:list>
    <bean id="person4" class="com.collection.Person">
        <property name="name" value="Jack"></property>
        <property name="age" value="29"></property>
        <property name="cars" ref="cars"></property>
    </bean>

此时再运行结果如下

Person{name='Jack', age=29, cars=[Car{brand='Audi', corp='ShangHai', price=300000.0, maxSpeed=0}, Car{brand='Baoma', corp='Tianjin', price=0.0, maxSpeed=200}]}

使用 p 命名空间

为了简化 XML 文件的配置,越来越多的 XML 文件采用属性而非子元素配置信息。

Spring 2.5 版本开始引入了一个新的 p 命名空间,可以通过 <bean> 元素属性的方式配置 Bean 的属性。

使用 p 命名空间后,基于 XML 的配置方式将进一步简化

 <!--通过p命名空间为bean的属性赋值,需先导入p命名空间,相对于传统的配置方式更加简洁-->
    <bean id="person5" class="com.collection.Person" p:age="30" p:name="Queen" p:cars-ref="cars"></bean>

运行结果

Person{name='Queen', age=30, cars=[Car{brand='Audi', corp='ShangHai', price=300000.0, maxSpeed=0}, Car{brand='Baoma', corp='Tianjin', price=0.0, maxSpeed=200}]}

注:该博客主要说明了配置bean的一些细节,如果不明白可以先看看前面几篇博客

猜你喜欢

转载自blog.csdn.net/QuZDLvT/article/details/81414684