Spring学习笔记之Bean的属性注入

自建博客地址:https://www.bytelife.net,欢迎访问! 本文为博客自动同步文章,为了更好的阅读体验,建议您移步至我的博客👇

本文作者: Jeffrey
本文链接: https://www.bytelife.net/articles/61060.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!


通常,JavaBean的属性值是私有的,同时拥有一组存取器方法,以setXxx()和getXxx()的形式存在。Spring通过Java 的反射机制借助属性的set方法来配置属性的值,以实现setter方式的注入。

下面定义一个Person类来演示Spring Bean的属性注入:

package cn.javacodes.spring.beans;
/**
 * Created by eric on 16-8-31.
 */
public class Person {
    private String name;
    private int age;
    private String sex;
    private String resume;
    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 String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getResume() {
        return resume;
    }
    public void setResume(String resume) {
        this.resume = resume;
    }
    public Car getCar() {
        return car;
    }
    public void setCar(Car car) {
        this.car = car;
    }
    public Person(String name, int age, String sex, String resume) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.resume = resume;
    }
    public Person(String name, int age, String sex, String resume, Car car) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.resume = resume;
        this.car = car;
    }
    public Person() {
    }
}

Person类中包含一个无参的构造方法,因此可以在Spring中使用下面的XML声明一个

<bean id="person" class="cn.javacodes.spring.beans.Person"></bean>

通过上面的XML生命的没有对任何属性进行赋值,下面逐步讲解如何为属性进行赋值。

一、注入简单值(字面值)

1、通过value属性注入

在Spring中可以使用元素配置Bean的属性。例如现在想给bean person的姓名、年龄、性别、简历等属性赋值,那么可以使用下面的方式:

    <bean id="person" class="cn.javacodes.spring.beans.Person">
        <property name="name" value="张三"></property>
        <property name="age" value="16"></property>
        <property name="sex" value="男"></property>
        <property name="resume" value="疯狂的Java码农"></property>
    </bean>

一旦Person被实例化,Spring就会调用元素所指定属性的setter方法为该属性注入值。在本实例中,name、sex、resume属性均为String类型的字符串,而我们发现int类型的age属性也可以成功注入简单值,这是因为元素并没有限制只能注入String类型的值,value属性同样可以指定为基本数据类型(包括数值型和布尔型等)。

2、通过子元素注入

那么我们想象一下,如果我们想注入的值中包含XML的特殊字符怎么办,上述方法是否仍然奏效?不妨尝试一下,例如我想将person的resume属性注入值“”,那么在这个值中,“<>”在XML中拥有特殊的含义,如果仍然使用value属性进行赋值,将会出现异常!

Exception in thread "main" org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 11 in XML document from class path resource [applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 11; columnNumber: 40; 与元素类型 "property" 相关联的 "value" 属性值不能包含 '<' 字符。

那么如何解决这个问题呢?元素中可以添加一个子元素,其作用与value属性基本相同,而当我们想要注入包含特殊字符的字面值时,可以在子元素中使用CDATA节来解决,例如:

    <bean id="person" class="cn.javacodes.spring.beans.Person">
        <property name="name" value="张三"></property>
        <property name="age" value="16"></property>
        <property name="sex" value="男"></property>
        <property name="resume">
            <value><![CDATA[<Coder!>]]></value>
        </property>
    </bean>

二、引用其他Bean

上面使用value属性或子元素注入简单值只是实现简单的硬编码,而在实际开发过程中,经常需要为某一个属性赋值为一个对象,通常为另一个bean。那么如何在Spring中为属性引用其他bean呢?

例如本例中Person实例拥有一个Car类型的属性car,可以使用元素的ref属性为其进行赋值。类Car的源码如下:

package cn.javacodes.spring.beans;
/**
 * Created by huzha on 2016-09-06.
 */
public class Car {
    private String brand;
    private String model;
    private String color;
    public Car() {
    }
    public Car(String brand, String model, String color) {
        this.brand = brand;
        this.model = model;
        this.color = color;
    }
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public String getModel() {
        return model;
    }
    public void setModel(String model) {
        this.model = model;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + ''' +
                ", model='" + model + ''' +
                ", color='" + color + ''' +
                '}';
    }
}

我们首先在XML中声明一个Car类型的,源码如下:

    <bean id="car" class="cn.javacodes.spring.beans.Car">
        <property name="brand" value="奥迪"></property>
        <property name="model" value="A6"></property>
        <property name="color" value="黑色"></property>
    </bean>

那么可以在person bean中引用这个bean,源码如下:

    <bean id="person" class="cn.javacodes.spring.beans.Person">
        <property name="name" value="张三"></property>
        <property name="age" value="16"></property>
        <property name="sex" value="男"></property>
        <property name="resume">
            <value><![CDATA[<Coder!>]]></value>
        </property>
        <property name="car" ref="car"></property>
    </bean>

三、注入内部Bean

我们知道,在Spring中bean的默认作用域是单例的,通过上述方式注入bean,意味着这个bean还可能被其他bean引用。例如,可能有另外一个Person类型的bean person1,其car属性同样引用的是id为car的bean,那么意味着这两个人同时拥有同一台奥迪A6,这通常是不现实的。那么如何为一个Bean创建一个独有的内部bean呢?

在Spring中元素中还可以嵌套其它的元素,我们称嵌套在内部的为内部bean,这个概念与Java的内部类十分相似。

我们修改一下person的声明,代码如下:

    <bean id="person" class="cn.javacodes.spring.beans.Person">
        <property name="name" value="张三"></property>
        <property name="age" value="16"></property>
        <property name="sex" value="男"></property>
        <property name="resume">
            <value><![CDATA[<Coder!>]]></value>
        </property>
        <property name="car">
            <bean class="cn.javacodes.spring.beans.Car">
                <property name="brand" value="奥迪"></property>
                <property name="model" value="A6"></property>
                <property name="color" value="黑色"></property>
            </bean>
        </property>
    </bean>

这样我们就成功的注入了一个内部Bean。细心的朋友可能会发现,在这里内部bean没有给定其id属性,因为在这里其id属性似乎并不是那么必要,因为我们永远不会通过id来引用内部bean。这也突出了内部Bean的最大缺点:它们不能被复用。内部Bean仅适用于一次注入,而且也不能被其它Bean所引用。

内部Bean并不局限于在元素中使用,我们同样可以在中使用,例如我们修改person的声明如下:

    <bean id="person" class="cn.javacodes.spring.beans.Person">
        <constructor-arg value="张三"></constructor-arg>
        <constructor-arg value="16"></constructor-arg>
        <constructor-arg name="sex" value="男"></constructor-arg>
        <constructor-arg >
            <value><![CDATA[<Coder!>]]></value>
        </constructor-arg>
        <constructor-arg>
            <bean class="cn.javacodes.spring.beans.Car">
                <constructor-arg name="brand" value="奥迪"></constructor-arg>
                <constructor-arg name="model" value="A6"></constructor-arg>
                <constructor-arg name="color" value="黑色"></constructor-arg>
            </bean>
        </constructor-arg>
    </bean>
posted @ 2021-02-25 01:17  JeffreyHu  阅读(150)  评论(0编辑  收藏  举报