Spring系列5:各种属性值依赖注入

回顾

上一篇我们介绍Spring中2种依赖注入的方式:

  • 构造函数注入,主要的标签是<constructor-arg/>
  • Setter方法注入,主要的标签是<property/>

那么问题来了,普通类型的依赖怎么注入,集合依赖怎么注入,null怎么注入?本篇全面了解下。

本文内容

  1. 普通类型和字符串注入
  2. 引用类型的注入
  3. 集合的注入
  4. 内部bean注入
  5. null和空字符串注入
  6. 复合属性注入

普通类型和字符串注入

基本类型和字符串,通过value元素直接指定值。上案例,对照类和配置。

package com.crab.spring.ioc.demo03;

/**
 * @author zfd
 * @version v1.0
 * @date 2022/1/13 15:07
 * @关于我 请关注公众号 螃蟹的Java笔记 获取更多技术系列
 */
public class SimpleBean {
    private String name;
    private int age;
    private float height;
	// 省略 Getter Setter toString()
}

    <bean class="com.crab.spring.ioc.demo03.SimpleBean" id="simpleBean">
        <property name="name" value="xxx"/>
        <property name="age" value="12"/>
        <property name="height"  value="123.45f"/>
    </bean>

引用类型的注入

引用类型类型通过ref标签设置。

public class MyBean {

    private RefBean refBean;

    public void setRefBean(RefBean refBean) {
        this.refBean = refBean;
    }
}

public class RefBean {
}
    <!--    引用类型-->
<bean class="com.crab.spring.ioc.demo03.RefBean" id="refBean"/>
<bean class="com.crab.spring.ioc.demo03.MyBean" id="myBean">
    <property name="refBean" >
        <ref bean="refBean"/>
    </property>
</bean>

注意: ref 元素的本地属性在 4.0 bean XSD 中不再受支持,因为它不再提供常规 bean 引用的值。升级到 4.0 模式时,将现有的 ref 本地引用更改为 ref bean。如下例子

// 4.0前
<property name="refBean" ref="refBean" >
// 4.0改成
<property name="refBean" >
	<ref bean="refBean"/>
</property>

内部bean注入

<property/><constructor-arg/> 元素中的 <bean/> 元素定义了一个内部 bean。内部 bean 始终是匿名的,并且始终使用外部 bean 创建。无法独立访问内部 bean 或将它们注入到别的 bean中

    <!--    内部bean的方式-->
    <bean class="com.crab.spring.ioc.demo03.MyBean" id="myBean">
        <property name="refBean">
            <bean class="com.crab.spring.ioc.demo03.RefBean"/>
        </property>
    </bean>

集合的注入

<list/>、<set/><map/><props/> 元素分别设置Java 集合类型List、Set、Map 和Properties 的属性和参数。<map/>键或值,<set/>的值也可以是以下任何元素:

bean | ref | idref | list | set | map | props | value | null

集合注入综合案例

一个综合样例满足你。

package com.crab.spring.ioc.demo03;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * @author zfd
 * @version v1.0
 * @date 2022/1/13 15:53
 * @关于我 请关注公众号 螃蟹的Java笔记 获取更多技术系列
 */
public class ComplexObject {
    //属性
    private Properties adminEmails;
    //列表
    private List<Object> someList;
    // map
    private Map<String, Object> someMap;
    // set
    private Set<Object> someSet;
	// 省略 Getter Setter
}
<!--    集合-->
    <bean class="com.crab.spring.ioc.demo03.ComplexObject" id="complexObject">
        <property name="adminEmails">
            <props>
                <prop key="administrator">administrator@example.org</prop>
                <prop key="support">support@example.org</prop>
                <prop key="development">development@example.org</prop>
            </props>
        </property>
        <!-- results in a setSomeList(java.util.List) call -->
        <property name="someList">
            <list>
                <value>a list element followed by a reference</value>
                <ref bean="myBean" />
            </list>
        </property>
        <!-- results in a setSomeMap(java.util.Map) call -->
        <property name="someMap">
            <map>
                <entry key="an entry" value="just some string"/>
                <entry key="a ref" value-ref="myBean"/>
            </map>
        </property>
        <!-- results in a setSomeSet(java.util.Set) call -->
        <property name="someSet">
            <set>
                <value>just some string</value>
                <ref bean="myBean" />
            </set>
        </property>
    </bean>

集合元素的合并

Spring 容器支持合并集合。可以定义在父bean中定义 <list/><map/><set/><props/> 元素,子bean中 <list/><map/><set/><props/> 元素从父集合继承。也就是说,子bean的集合的值是合并父集合和子集合的元素的结果,子集合元素覆盖父集合中指定的值。注意: 结合类型要一致,如都是List

    <!--    集合合并-->
    <bean id="parent" abstract="true" class="com.crab.spring.ioc.demo03.ComplexObject">
        <property name="adminEmails">
            <props>
                <prop key="administrator">administrator@example.com</prop>
                <prop key="support">support@example.com</prop>
            </props>
        </property>
    </bean>
    <bean id="child" parent="parent">
        <property name="adminEmails">
            <!-- the merge is specified on the child collection definition -->
            <props merge="true">
                <prop key="sales">sales@example.com</prop>
                <prop key="support">support@example.co.uk</prop>
            </props>
        </property>
    </bean>

集合元素指定类型

综合案例中的集合元素类型都是Object,Spring中也支持指定更具体的类型如Integer。来个例子。

public class AccountBean {
    private Map<String, Float> accounts;

    public void setAccounts(Map<String, Float> accounts) {
        this.accounts = accounts;
    }
}
    <!--    集合元素指定类型-->
    <bean id="accountBean" class="com.crab.spring.ioc.demo03.AccountBean">
        <property name="accounts">
            <map>
                <entry key="one" value="9.99"/>
                <entry key="two" value="2.75"/>
                <entry key="six" value="3.99"/>
            </map>
        </property>
    </bean>	

null和空字符串注入

null和空字符串注入很简单,直接看案例。

public class EmptyStringBean {
    private String name;
    private Integer code;
    // 省略 Getter Setter
}
    <!--    `null`和空字符串注入-->
    <bean class="com.crab.spring.ioc.demo03.EmptyStringBean">
        <property name="name" value=""/>
        <property name="code">
            <null></null>
        </property>
    </bean>

复合属性注入

在设置 bean 属性时使用复合或嵌套属性名称,只要路径的所有对象(最终属性名称除外)不为空即可,中间对象为null将引发 NullPointerException。直接看案例

public class NestedBean {
    private SimpleBean simpleBean;

    public SimpleBean getSimpleBean() {
        return simpleBean;
    }

    public void setSimpleBean(SimpleBean simpleBean) {
        this.simpleBean = simpleBean;
    }
}
    <!--    复合属性-->
    <bean class="com.crab.spring.ioc.demo03.NestedBean" id="nestedBean">
        <property name="simpleBean.name" value="xxx"/>
    </bean>

总结

本文介绍各种依赖属性如何注入到bean中,内容非常详细,建议动手写一下案例实践并消化,毕竟好记性不如烂笔头,站在岸上学不会游泳。

本篇源码地址: https://github.com/kongxubihai/pdf-spring-series/tree/main/spring-series-ioc/src/main/java/com/crab/spring/ioc/demo03
知识分享,转载请注明出处。学无先后,达者为先!

点赞