Spring实例解析之XML装配Bean

Spring实例解析之XML装配Bean

@(Spring)
*本文主要参考Spring in action(第三版),并以自己的实例进行了实现。

在Spring中容器负责把需要相互协作的对象引用赋予各个对象。创建应用对象之间协作关系的行为通常称为装配(wiring)

1.maven依赖

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>

2.声明Bean

本文将围绕People接口,来渐渐展开。

public interface People {
    void doWorking();
}
2.1 声明简单Bean

Himma(搬砖工)实现People接口。并有两个参数,birckNum(砖头数),pitNum(填坑数)。

package com.spring;

public class Himma implements People {
    //默认一天搬100块砖
    private Integer brickNum = 100;
    //默认填5个坑
    private Integer pitNum = 5;

    public Himma(){

    }

    public Himma(int brickNum){
        this.brickNum = brickNum;
    }

    public Himma(int brickNum, int pitNum){
        this.brickNum = brickNum;
        this.pitNum= pitNum;
    }

    public void doWorking() {
        System.out.println("今天搬了"+brickNum+"块砖,还填了"+pitNum+"个坑");
    }

    public void setBrickNum(Integer brickNum) {
        this.brickNum = brickNum;
    }

    public void setPitNum(Integer pitNum) {
        this.pitNum = pitNum;
    }

}
2.2 创建Spring的XML配置

传统的XML文件配置方式。

<?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-2.0.xsd">

    <!-- xiaoMing,实现最基本bean配置 -->
    <bean id="xiaoMing" class="com.spring.Himma"></bean>

</beans>
2.3 初步实现
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Spring-Himma.xml");
        People xiaoming = (People)applicationContext.getBean("xiaoMing");
        xiaoming.doWorking();

运行结果:今天搬了100块砖,还填了5个坑

运行结果正常,由Spring实例化的bean正确执行了doWorking方法。

2.4 通过构造器注入

在Spring-Himma.xml中配置,分别实现了构造器注入的几种方式。

    <!-- xiaoHong,通过构造器注入 -->
    <bean id="xiaoHong" class="com.spring.Himma">
        <constructor-arg value="300"></constructor-arg>
    </bean>

    <!-- xiaoHong,通过构造器注入,指定参数类型。-->
    <!-- 如果构造函数都只有一个参数,一个类型为String,一个类型为int,那么Spring将会调用参数类型为String的构造函数 -->
    <!--
    <bean id="xiaoHong" class="com.spring.Himma">
        <constructor-arg type="int" value="300"></constructor-arg>
    </bean>    
    -->




    <!-- xiaoGang,通过构造器注入多参数,默认按构造器参数顺序,也可以指定顺序 -->
    <bean id="xiaoGang" class="com.spring.Himma">
        <constructor-arg value="300"></constructor-arg>
        <constructor-arg value="20"></constructor-arg>
    </bean>

    <!-- xiaoGang,指定参数顺序的构造器注入-->
    <!-- 
    <bean id="xiaoGang" class="com.spring.Himma">
        <constructor-arg value="300" index="0"></constructor-arg>
        <constructor-arg value="20" index="1"></constructor-arg>
    </bean>
    -->
2.5 Bean的作用域
作用域定义
singleton在每一个Spring容器中,一个bean定义只有一个对象实例(默认)
prototype每次调用都创建一个实例
request在一次http请求中,每个bean定义对应一个实例。仅在基于web的Spring上下文中有效
session在一次http session请求中,每个bean定义对应一个实例。仅在基于web的Spring上下文中有效
global-session在一个全局http session中,每个bean定义对应一个实例。仅在Portlet上下文中有效

增添新的类SingHimma。里面增加了一个Song的引用,在其搬砖的时候还能唱首歌。

package com.spring;

public class SingHimma extends Himma{
    private Song song;

    public SingHimma(){

    }

    public SingHimma(Song song){
        this.song = song;
    }

    public SingHimma(int brickNum,Song song){
        super(brickNum);
        this.song = song;
    }

    @Override
    public void doWorking() {
        // TODO Auto-generated method stub
        super.doWorking();
        System.out.println("开始唱歌。。");
        song.sing();
    }

    public void setSong(Song song) {
        this.song = song;
    }

    public void startWork(){
        System.out.println("开始上班了");
    }

    public void endWork(){
        System.out.println("下班了");
    }

}
package com.spring;

public interface Song {
    void sing();
}

FadedSong,SugerSong实现了Song 接口

package com.spring;

public class FadedSong implements Song{

    public void sing() {
        // TODO Auto-generated method stub
        System.out.println("You were the shadow to my light....Did you feel us....");
    }

}


package com.spring;

public class SugerSong implements Song{

    public void sing() {
        // TODO Auto-generated method stub
        System.out.println("I'm hurtin baby, I'm broken down...I need your lovin, lovin I need it now...");
    }
}
    <!-- 通过构造器注入对象引用 -->
    <bean id="xiaoXia" class="com.spring.SingHimma">
        <constructor-arg value="500"></constructor-arg>
        <constructor-arg ref="fadedSong"></constructor-arg>

    </bean>


    <!-- 通过构造器注入对象引用,使用prototype作用域 -->
    <bean id="xiaoZhi" class="com.spring.SingHimma" scope="prototype">
        <constructor-arg value="500"></constructor-arg>
        <constructor-arg ref="fadedSong"></constructor-arg>
    </bean>

    <bean id="fadedSong" class="com.spring.FadedSong"></bean>

使用junit来演示scope为默认的singleton与prototype的情况

    @Before
    public void setUp() throws Exception {
        applicationContext = new ClassPathXmlApplicationContext(
                "Spring-SingHimma.xml");
    }
    @Test
    public void testxiaoZhi() {
        // xiaoXia默认作用域为singleton
        SingHimma xiaoXia = (SingHimma) applicationContext.getBean("xiaoXia");
        xiaoXia.doWorking();

        // 给xiaoXia一首新歌
        xiaoXia.setSong(new SugerSong());

        // 重新从Spring容器中取得xiaoXia,发现song变成了SugerSong
        SingHimma xiaoXia2 = (SingHimma) applicationContext.getBean("xiaoXia");
        xiaoXia2.doWorking();

        // xiaoZhi作用域为prototype
        SingHimma xiaoZhi = (SingHimma) applicationContext.getBean("xiaoZhi");
        xiaoZhi.doWorking();

        // 给xiaoZhi一首新歌
        xiaoZhi.setSong(new SugerSong());

        // 重新从Spring容器中取得xiaoZhi,发现song没有变化
        SingHimma xiaoZhi2 = (SingHimma) applicationContext.getBean("xiaoZhi");
        xiaoZhi2.doWorking();
    }

发现xiaoXia通过重新赋值后,第二次调用时song换成了SugerSong。而使用prototype的xiaoZhi则没有改变,两次调用都是同样在xml中配置的FadedSong

运行结果为:
今天搬了500块砖,还填了5个坑
开始唱歌。。
You were the shadow to my light….Did you feel us….
今天搬了500块砖,还填了5个坑
开始唱歌。。
I’m hurtin baby, I’m broken down…I need your lovin, lovin I need it now…

今天搬了500块砖,还填了5个坑
开始唱歌。。
You were the shadow to my light….Did you feel us….
今天搬了500块砖,还填了5个坑
开始唱歌。。
You were the shadow to my light….Did you feel us….

2.6 初始化和销毁Bean

观察SingHimma中可以发现两个方法startWork和endWork。可以在XML中将其配置为初始化方法和销毁方法。

    <!-- 添加指定的初始化方法和销毁方法 -->
    <bean id="xiaoXia" class="com.spring.SingHimma" init-method="startWork" destroy-method="endWork">
        <constructor-arg value="500"></constructor-arg>
        <constructor-arg ref="fadedSong"></constructor-arg>

    </bean>

调用执行

    @Before
    public void setUp() throws Exception {
        applicationContext = new ClassPathXmlApplicationContext(
                "Spring-SingHimma.xml");
    }

    @Test
    public void testxiaoXia() {
        People xiaoXia = (People) applicationContext.getBean("xiaoXia");
        xiaoXia.doWorking();
    }

    @After
    public void destroy() {
        // 关闭容器,演示destory-method
        ((ClassPathXmlApplicationContext) applicationContext).close();
    }

执行结果:
开始上班了
今天搬了500块砖,还填了5个坑
开始唱歌。。
You were the shadow to my light….Did you feel us….
下班了

2.7 注入Bean属性

XML配置,使用setter注入属性。

    <!-- 注入bean属性 -->
    <bean id="xiaoMei" class="com.spring.SingHimma">
        <!-- 注入简单值 -->
        <property name="brickNum" value="1000"></property>
        <property name="pitNum" value="50"></property>

        <!-- 装配空值 -->
        <!--
        <property name="pitNum"><null/></property>
        -->
        <!-- 引入其他Bean -->
        <property name="song" ref="fadedSong"></property>
        <!-- 引入内部Bean -->
        <!--
        <property name="song">
            <bean class="com.spring.FadedSong"></bean>
        </property>
        -->
    </bean>
2.8 装配集合
集合元素用途
<list>装配list类型的值,允许重复
<set>装配set类型的值,不允许重复
<map>装配map类型的值,名称和值可以是任意类型
<props>装配properties类型的值,名称和值必须都是String类型

为了实现装配集合的实例,增加一个新的类HimmaTeam,搬砖队。通过三种不同的集合注入来展示。

package com.spring;

import java.util.Collection;
import java.util.Map;
import java.util.Properties;

public class HimmaTeam implements People{


    private Collection<People> peoples;

    private Map<String, String> fruits;

    private Properties foods;


    public HimmaTeam(){
    }

    public void doWorking() {
        // TODO Auto-generated method stub
        for (People people : peoples) {
            people.doWorking();
        }

        for (String key : fruits.keySet()) {
            System.out.println(key+": 吃了"+ fruits.get(key));
        }

        for (Object key : foods.keySet()) {
              String keyStr = key.toString();
              String valueStr = foods.getProperty(keyStr);
              System.out.println(keyStr + ": 吃了"+valueStr);

        }

    }

    public void setPeoples(Collection<People> peoples) {
        this.peoples = peoples;
    }

    public void setFruits(Map<String, String> fruits) {
        this.fruits = fruits;
    }

    public void setFoods(Properties foods) {
        this.foods = foods;
    }
}

XML配置


    <!-- 引入Himma与SingHimma的上下文配置 -->
    <import resource="Spring-Himma.xml"/>    
    <import resource="Spring-SingHimma.xml"/>    

    <bean name="blueTeam" class="com.spring.HimmaTeam">

        <property name="peoples">
        <!-- 装配list集合 -->
            <list>
                <ref bean="xiaoMing"/>
                <ref bean="xiaoHong"/>
                <ref bean="xiaoMei"/>
            </list>
        </property>
        <!-- 装配map集合 -->
        <property name="fruits">
            <map>
                <entry key="apple" value="苹果"></entry>
                <entry key="banana" value="香蕉"></entry>
                <entry key="pears" value="梨子"></entry>
            </map>
        </property>
        <!-- 装配properties集合 -->
        <property name="foods">
            <props>
                <prop key="rice">米饭</prop>
                <prop key="noodles">面条</prop>
                <prop key="bread">面包</prop>
            </props>
        </property>


    </bean>

结果:
开始上班了
今天搬了100块砖,还填了5个坑
今天搬了300块砖,还填了5个坑
今天搬了1000块砖,还填了50个坑
开始唱歌。。
You were the shadow to my light….Did you feel us….
apple: 吃了苹果
banana: 吃了香蕉
pears: 吃了梨子
bread: 吃了面包
noodles: 吃了面条
rice: 吃了米饭
下班了

3.小结

以上为Spring的XML装配Bean的一个简单例子。附上github的地址:https://github.com/JunliXia/Spring_WiringBean

4.参考

Spring in action
http://jingyan.baidu.com/article/11c17a2c749a61f446e39d94.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值