Spring与IoC之基于XML的DI

12 篇文章 0 订阅

注入分类

Bean 实例在调用无参构造器创建了空值对象后,就要对 Bean 对象的属性进行初始化。初始化是由容器自动完成的, 称为注入。根据注入方式的不同, 常用的有两类: 设值注入、构造注入(接口注入几乎不用)。

设值注入

设值注入是指,通过 setter 方法传入被调用者的实例(底层通过调用 setter 方法将值注入)。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。

(1) 定义实体类

public class School {
	private String name;

}
public class Student {
	private String name;
	private int age;
	private School school;
	public void setName(String name) {
		System.out.println("执行setName()");
		this.name = name;
	}
}

(2) 创建 Spring 配置文件

    <!-- 注册School -->
    <bean id="mySchool" class="com.huang.di01.School">
    	<property name="name" value="清华大学"/>
    </bean>
    
    <!-- 注册Student -->
    <bean id="myStudent" class="com.huang.di01.Student">
    	<property name="name" value="张三"/>
    	<property name="age" value="22"/>
    	<property name="school" ref="mySchool"/>
    </bean>

(3) 定义测试类

	@Test
	public void test01() {
		String resource = "com/huang/di01/applicationContext.xml";
		ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
		Student student = (Student) ac.getBean("myStudent");
		System.out.println(student);
	}

(4) 运行结果

{% asset_img spring12.jpg %}

当指定 bean 的某属性值为另一 bean 的实例时,通过 ref 指定它们间的引用关系。 ref 的值必须为某 bean 的 id 值(域属性(引用类型)的注入需要使用 ref 属性,字符串和基本数据类型使用 value)。对于其它 Bean 对象的引用,除了<bean/>标签的 ref 属性外,还可以使用<ref/>标签。

构造注入

构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即,使用构造器设置依赖关系(底层调用的是构造器)。

(1) 修改实现类

{% asset_img spring13.jpg %}

(2) 修改 Spring 配置文件

{% asset_img spring14.jpg %}

<constructor-arg />标签中用于指定参数的属性有:

  • name:指定参数名称。
  • index:指明该参数对应着构造器的第几个参数,从 0 开始。不过,该属性不要也行,但要注意,若参数类型相同,或之间有包含关系,则需要保证赋值顺序要与构造器中的参数顺序一致。

命名空间注入

对于设值注入与构造注入,在配置文件中,除了使用<property/>或<constructor-arg/>标签外,还可使用命名空间注入的方式,让注入的值以<bean/>标签属性的方式出现。根据注入实现方式的不同,分为:

p 命名空间注入:采用设值注入方式,故需要有相应的 setter
c 命名空间注入:采用构造注入方式,故需要有相应的构造器

p 命名空间设值注入

{% asset_img spring15.jpg %}

c 命名空间构造注入

{% asset_img spring16.jpg %}

集合属性注入

(1) 定义实体类

public class Some {
	private School[] schools;
	private String[] myStrs;
	private List<String> myList;
	private Set<String> mySet;
	private Map<String, Object> myMap;
	private Properties myPros;

}

(2) 修改 Spring 配置文件

    <!-- 注册School -->
    <bean id="mySchool" class="com.huang.di05.School">
    	<property name="name" value="清华大学"/>
    </bean>
    <bean id="mySchool2" class="com.huang.di05.School">
    	<property name="name" value="北京大学"/>
    </bean>
    
    <!-- 注册Student -->
    <bean id="mySome" class="com.huang.di05.Some">
        <property name="schools">
            <array>
                <ref bean="mySchool"/>
                <ref bean="mySchool2"/>
            </array>
        </property>
        
        <!-- 为数组注入值 -->
        <property name="myStrs">
            <array>
                <value>中国</value>
                <value>广东</value>
            </array>
        </property>
        
        <!-- 为 List 注入值 -->
        <property name="myList">
            <list>
                <value>广州</value>
                <value>天河</value>
            </list>
        </property>
        
        <!-- 为 Set 注入值 -->
        <property name="mySet">
            <set>
                <value>现代学院</value>
                <value>信息工程系</value>
            </set>
        </property>
        
        <!-- 为 Map 注入值 -->
        <property name="myMap">
            <map>
               <entry key="mobile" value="1234567"/>
               <entry key="QQ" value="7654321"/>
            </map>
        </property>
        
        <!-- 为 Properties 注入值 -->
        <property name="myPros">
            <props>
                <prop key="education">大学</prop>
                <prop key="gender"></prop>
            </props>
        </property>
        
    </bean>

Spring 配置文件的简单赋值

{% asset_img spring17.jpg %}

对于域属性的自动注入

对于域属性的注入,也可不在配置文件中显示的注入。可以通过为<bean/>标签设置 autowire 属性值,为域属性进行隐式自动注入。根据自动注入判断标准的不同,可以分为两种:

  • byName:根据名称自动注入
  • byType:根据类型自动注入

(1) byName 方式自动注入

当配置文件中被调用者 Bean 的 id 值与代码中调用者 Bean 类的属性名相同时,可使用 byName 方式,让容器自动将被调用者 Bean 注入给调用者 Bean。容器是通过调用者的 Bean 类的属性名与配置文件的被调用者 bean 的 id 进行比较而实现自动注入的。

{% asset_img spring18.jpg %}

(2) byType 方式自动注入

使用 byType 方式自动注入,要求:配置文件中被调用者 bean 的 class 属性指定的类,要与代码中调用者 Bean 类的某域属性类型同源。即要么相同,要么有 is-a 关系(子类,或是实现类)。

{% asset_img spring19.jpg %}

使用 SPEL 注入

SPEL(Spring Expression Language),即 Spring EL 表达式语言。即,在 Spring 配置文件中为 Bean 的属性注入值时,可直接使用 SPEL 表达式计算的结果。 SPEL 表达式以#开头,后跟一对大括号。

用法: <bean id=“abc” value=“#{…}”/>。

{% asset_img spring20.jpg %}

其它用法:
(1) <property name=“school” value=“#{mySchool}”/>:引用另一个 bean。指定 school 的值为另一个 Bean 实例 mySchool。
(2) <property name=“schoolName” value=“#{mySchool.name.toUpperCase()}”/>:使用指定属性,并使用其方法。指定 schoolName 的值为 mySchool 的 name 属性值,并将其字母均转换为大写字母(toUpperCase()方法)。

使用内部 Bean 注入

若不希望代码直接访问某个 bean,即,在代码中通过 getBean 方法获取该 Bean 实例,则可将该 Bean 的定义放入调用者 bean 定义的内部。

{% asset_img spring21.jpg %}

使用同类抽象 Bean 注入

当若干 Bean 实例同属于一个类,且这些实例的属性值又有相同值时,可以使用抽象Bean,以简化配置文件。

抽象 Bean 是用于让其它 bean 继承的。这个 bean 在 Bean 类中是不能通过 getBean 方法获取的。设置 abstract 属性为 true 来指明该 bean 为抽象 bean, 默认值为 false。 不过,该 bean 不为抽象 bean 时,也可被继承。 只不过,在应用中,用于被继承的 bean 一般为抽象 bean。

{% asset_img spring22.jpg %}

使用异类抽象 Bean 注入

当若干不同的类对象具有相同的属性,且其值也相同时,可使用异类抽象 Bean。

{% asset_img spring23.jpg %}

为应用指定多个 Spring 配置文件

在实际应用里,随着应用规模的增加,系统中 Bean 数量也大量增加,导致配置文件变得非常庞大、臃肿。为了避免这种情况的产生,提高配置文件的可读性与可维护性,可以将 Spring 配置文件分解成多个配置文件。

(1)平等关系的配置文件
将配置文件分解为地位平等的多个配置文件,并将所有配置文件的路径定义为一个 String 数组,将其作为容器初始化参数出现。 其将与可变参的容器构造器匹配。

( 2)包含关系的配置文件
各配置文件中有一个总文件,总配置文件将各其它子文件通过<import/>引入。在 Java 代码中只需要使用总配置文件对容器进行初始化即可。

Spring 配置文件中也可使用通配符*。但,此时要求总配置文件不要和子配置文件命名格式相同,否则将出现循环递归包含。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值