Spring xml注入实例

spring是十分优秀的开源框架,大量的java web项目受益于spring,控制反转和切面编程是spring的两大特点,上次我有实践简单的注入实例,也结合了注解去完成了注解的装配和bean注册,这次我们以更多的方法去解决xml的注入问题,相信掌握好了xml的注入,注解使用起来会更加得心应手。
首先我们来创建工程目录:
这里写图片描述
最开始我创建了一个包将applicationContext.xml放到该包下面,总是无法加载容器,后来放到了根包下面,问题得到了解决。
这次主要是注入的练习,web.xml里并没有配置什么。
首先我们来实践一个声明接口,注入实现类的练习:
声明一个接口:

public interface UserDao {
//定义一个save方法 
    public void save();
}

实现类不仅实现了save方法,我还添加了一系列的成员变量,来完成注入练习:

package dao;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;

import entity.Person;

public class UserDaoImpl implements UserDao {
    private String name;
    //构造注入
//  UserDaoImpl(String name)
//  {
//      this.name = name;
//  }
    //依赖注入一个p1
    private Person p;
    public Person getP() {
        return p;
    }

    public void setP(Person p) {
        this.p = p;
    }
    //注入集合list
    private ArrayList list;
    public ArrayList getList() {
        return list;
    }

    public void setList(ArrayList list) {
        this.list = list;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    //注入集合set
    private HashSet set;

    public HashSet getSet() {
        return set;
    }

    public void setSet(HashSet set) {
        this.set = set;
    }

    //注入集合map
    private Map map;

    public Map getMap() {
        return map;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    //实现的方法
    @Override
    public void save() {
        // TODO Auto-generated method stub
        System.out.println("this is a UserDaoImpl");
    }

}

继续造轮子,不仅有集合的几种注入,我还新建了一个构造方法,注入四个不同类型的参数:

public class ContextTest {
    private String str;
    private Person person;
    private int id;
    private List list;
    public String getStr() {
        return str;
    }
    public List getList() {
        return list;
    }
    public void setList(List<Integer> list) {
        this.list = list;
    }
    public Person getPerson() {
        return person;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    //三个构造参数,拿来构造注入使用,因此这个bean省略了setter
    ContextTest(String str,Person person,int id,List list)
    {
        this.str = str;
        this.person = person;
        this.id = id;
        this.list = list;
    }
}

几个实体类:

public class Parent {
    protected String parentName;
    protected int ParentAge;
    public String getParentName() {
        return parentName;
    }
    public void setParentName(String parentName) {
        this.parentName = parentName;
    }
    public int getParentAge() {
        return ParentAge;
    }
    public void setParentAge(int parentAge) {
        ParentAge = parentAge;
    }
}
public class Person {
    private String name;
    private int age;
    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 class Son extends Parent {
    private String sonName;
    private int sonAge;
    public String getSonName() {
        return sonName;
    }
    public void setSonName(String sonName) {
        this.sonName = sonName;
    }
    public int getSonAge() {
        return sonAge;
    }
    public void setSonAge(int sonAge) {
        this.sonAge = sonAge;
    }
}

spring容器配置applicationContext:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    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-3.0.xsd  
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- 构造注入 <bean id = "UserDaoImpl1" class = "dao.UserDaoImpl"> <constructor-arg 
        value="constructor's method"></constructor-arg> </bean> -->

    <!-- -->
    <bean id="UserDaoImpl2" class="dao.UserDaoImpl" scope="singleton">
        <property name="name" value="Singleton's setter method" />
    </bean>

    <bean id="Person1" class="entity.Person">
        <property name="name" value="micro" />
        <property name="age" value="1"></property>
    </bean>

    <!-- UserDaoImpl里面依赖注入Person -->
    <bean id="UserDaoImpl4" class="dao.UserDaoImpl">
        <property name="name" value="personImpl" />
        <property name="p" ref="Person1"></property>
    </bean>

    <!-- 内部属性注入 -->
    <bean id="UserDaoImpl5" class="dao.UserDaoImpl">
        <property name="p">
            <bean id="temp" class="entity.Person">
                <property name="name" value="nestProperty" />
                <property name="age" value="22"></property>
            </bean>
        </property>
    </bean>

    <!-- 注入集合list -->
    <bean id="UserDaoImpl3" class="dao.UserDaoImpl">
        <property name="list">
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </list>
        </property>
    </bean>

    <!-- 注入集合set -->
    <bean id="UserDaoImpl6" class="dao.UserDaoImpl">
        <property name="set">
            <set>
                <value>1</value>
                <value>1</value>
                <value>2</value>
            </set>
        </property>
    </bean>

    <!-- 注入集合map -->
    <bean id="UserDaoImpl7" class="dao.UserDaoImpl">
        <property name="map">
            <map>
                <entry key="1" value="micro1" />
                <entry key="2" value="micro2" />
            </map>
        </property>
    </bean>

    <!-- 注册一个parent bean -->
    <bean id="parent1" class="entity.Parent">
        <property name="parentName" value="myParent" />
        <property name="parentAge" value="50" />
    </bean>
    <!-- 子类 ,拥有parentName与parentAge属性的注入值 -->
    <bean id="son1" class="entity.Son" parent="parent1">
        <property name="sonName" value="myName" />
        <property name="sonAge" value="22" />
    </bean>

    <!-- 四个构造参数的ContextText -->
    <bean id="context1" class="dao.ContextTest">
        <constructor-arg index="0" value="contextStr" />
        <constructor-arg index="1" ref="Person1" />
        <!-- 这里可以用index指定参数位置,从0开始,也可以用名字出指定构造参数的名字 -->
        <constructor-arg name="id" value="10" />
        <constructor-arg index="3" >
            <list>
                <value>3</value>
                <value>4</value>
                <value>5</value>
            </list>
        </constructor-arg>
    </bean>
</beans>

最后测试:

    public static void main(String args[])
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//      UserDaoImpl userDao = (UserDaoImpl)context.getBean("UserDaoImpl1");
//      userDao.save();//调用实现类的方法,此处为动态绑定
//      System.out.println(userDao.getName());
        UserDaoImpl userDao = (UserDaoImpl)context.getBean("UserDaoImpl2");
        System.out.println(userDao.getName());
        Person p1 = (Person)context.getBean("Person1");
        System.out.println("Person1'name "+p1.getName()+"  Person1'age "+p1.getAge());

        //测试UserDaoImpl里的Person依赖注入是否为person1
        userDao = (UserDaoImpl)context.getBean("UserDaoImpl4");
        System.out.println("UserDaoImpl4里的Person的名字为:"+userDao.getP().getName()+"   年龄为:"+userDao.getP().getAge());

        //内部属性用bean注入
        userDao = (UserDaoImpl)context.getBean("UserDaoImpl5");
        System.out.println("UserdaoImpl5里的Person是采用内部bean去注入的,名字为:"+userDao.getP().getName()+" 年龄为:"+userDao.getP().getAge());

        //注入集合list
        userDao = (UserDaoImpl)context.getBean("UserDaoImpl3");
        List list = userDao.getList();
        for(Object o : list)
        {
            System.out.println(o.toString());
        }

        //注入集合set
        userDao = (UserDaoImpl)context.getBean("UserDaoImpl6");
        System.out.println("集合的大小为:"+userDao.getSet().size());
        for(Object o : userDao.getSet())
        {
            System.out.println(o.toString());
        }

        //注入集合map
        userDao = (UserDaoImpl)context.getBean("UserDaoImpl7");
        System.out.println(userDao.getMap().toString());

        //补充:HashMap的高效遍历方式
        Iterator iterator = userDao.getMap().entrySet().iterator();
        while(iterator.hasNext())
        {
            @SuppressWarnings("unchecked")
            Map.Entry entry = (Map.Entry)iterator.next();
            Object key = entry.getKey();
            Object value = entry.getValue();
            System.out.println("key = "+key+" value = "+value);
        }

        //创建两个bean,一个parent,一个son,son继承parent
        Son son = (Son)context.getBean("son1");
        System.out.println("son's parentName:"+son.getParentName()+" son's parentAge:"+son.getParentAge()+" son's sonName:"+son.getSonName()+" son's sonAge:"+son.getSonAge());

        //测试多个构造方法的bean  ContextTest
        ContextTest c = (ContextTest)context.getBean("context1");
        System.out.println("第一个构造参数str:"+c.getStr()+" 第二个构造参数person parentName,age依次为:"+c.getPerson().getName()+" "+c.getPerson().getAge()+" 第三构造参数id为:"+c.getId()+" 第四个构造参数list为"+c.getList());
    }

运行结果:
这里写图片描述

接下来,按照最后一个测试类中的代码,进行分析:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

这里是加载容器,应该放在根目录,否则会显示找不到容器。

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao)context.getBean("UserDaoImpl1");
        userDao.save();//调用实现类的方法,此处为动态绑定

这里从容器获得名字为UserDaoImpl1的bean并且使用接口回调使用接口的save方法。但是我在实现类里添加很多方法并不能使用,只能使用接口中定义的方法。
容器当中UserDaoImpl1是这样定义的:

 <bean id = "UserDaoImpl1" class = "dao.UserDaoImpl"> <constructor-arg 
        value="constructor's method"></constructor-arg> </bean>

这个实体类当中的构造方法为:

private String name;
    //构造注入
    UserDaoImpl(String name)
    {
        this.name = name;
    }
    //实现的方法
    @Override
    public void save() {
        // TODO Auto-generated method stub
        System.out.println("this is a UserDaoImpl and constructor to inject name : "+name);
    }

只有一个构造参数,所以直接写value就可以了,自动装配到该对象的name对象。
运行结果为:

this is a UserDaoImpl and constructor to inject name : constructor's method

接下来我们继续:

    UserDaoImpl userDao = (UserDaoImpl)context.getBean("UserDaoImpl2");
        System.out.println(userDao.getName());

容器定义注入:

<bean id="UserDaoImpl2" class="dao.UserDaoImpl">
        <property name="name" value="ref's setter method" />
    </bean>

这个为setter注入,实体类里一定要有对应属性的setter方法,否则无法注入。
运行结果为:

ref's setter method

我又创建一个实体类:

public class Person {
    private String name;
    private int age;
    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;
    }
}

采用setter注入:

<bean id="Person1" class="entity.Person">
        <property name="name" value="micro" />
        <property name="age" value="1"></property>
    </bean>

测试:

Person p1 = (Person)context.getBean("Person1");
        System.out.println("Person1'name "+p1.getName()+"  Person1'age "+p1.getAge());

运行结果:

Person1'name micro  Person1'age 1

继续给UserDaoImpl里添加一个对象注入:

private Person p;
    public Person getP() {
        return p;
    }

    public void setP(Person p) {
        this.p = p;
    }

容器里注入,就注入刚才我们定义那个Person1:

<!-- UserDaoImpl里面依赖注入Person -->
    <bean id="UserDaoImpl4" class="dao.UserDaoImpl">
        <property name="name" value="personImpl" />
        <property name="p" ref="Person1"></property>
    </bean>

测试:

//测试UserDaoImpl里的Person依赖注入是否为person1
        userDao = (UserDaoImpl)context.getBean("UserDaoImpl4");
        System.out.println("UserDaoImpl4里的Person的名字为:"+userDao.getP().getName()+"   年龄为:"+userDao.getP().getAge());

运行结果:

UserDaoImpl4里的Person的名字为:micro   年龄为:1

刚才是引用ref的方法去注入,起始还可以直接在property那里内部定义bean注入:

<!-- 内部属性注入 -->
    <bean id="UserDaoImpl5" class="dao.UserDaoImpl">
        <property name="p">
            <bean id="temp" class="entity.Person">
                <property name="name" value="nestProperty" />
                <property name="age" value="22"></property>
            </bean>
        </property>
    </bean>

注入的是个Person,别名叫temp,该对象的属性name为nestProperty,age为22
测试:

//内部属性用bean注入
        userDao = (UserDaoImpl)context.getBean("UserDaoImpl5");
        System.out.println("UserdaoImpl5里的Person是采用内部bean去注入的,名字为:"+userDao.getP().getName()+" 年龄为:"+userDao.getP().getAge());

运行结果:

UserdaoImpl5里的Person是采用内部bean去注入的,名字为:nestProperty 年龄为:22

然后我定义了一个集合ArrayList,在容器里这样去注入:

<!-- 注入集合list -->
    <bean id="UserDaoImpl3" class="dao.UserDaoImpl">
        <property name="list">
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </list>
        </property>
    </bean>

value里顺序分别为list里顺序。
同样下面是set和map的注入:


    <!-- 注入集合set -->
    <bean id="UserDaoImpl6" class="dao.UserDaoImpl">
        <property name="set">
            <set>
                <value>1</value>
                <value>1</value>
                <value>2</value>
            </set>
        </property>
    </bean>

    <!-- 注入集合map -->
    <bean id="UserDaoImpl7" class="dao.UserDaoImpl">
        <property name="map">
            <map>
                <entry key="1" value="micro1" />
                <entry key="2" value="micro2" />
            </map>
        </property>
    </bean>

当获取到了map,我想打印结果,遇到了一个问题,怎样去遍历,总之,如下这样去遍历是比较好的方法:

//补充:HashMap的高效遍历方式
        Iterator iterator = userDao.getMap().entrySet().iterator();
        while(iterator.hasNext())
        {
            @SuppressWarnings("unchecked")
            Map.Entry entry = (Map.Entry)iterator.next();
            Object key = entry.getKey();
            Object value = entry.getValue();
            System.out.println("key = "+key+" value = "+value);
        }

当然也可以在println()里直接打印map。直接打印的结果是:

{1=micro1, 2=micro2}

还可以在表明父类,使用注入的子类的时候,可以使用父类的成员变量。:

<!-- 注册一个parent bean -->
    <bean id="parent1" class="entity.Parent">
        <property name="parentName" value="myParent" />
        <property name="parentAge" value="50" />
    </bean>
    <!-- 子类 ,拥有parentName与parentAge属性的注入值 -->
    <bean id="son1" class="entity.Son" parent="parent1">
        <property name="sonName" value="myName" />
        <property name="sonAge" value="22" />
    </bean>

测试:

//创建两个bean,一个parent,一个son,son继承parent
        Son son = (Son)context.getBean("son1");
        System.out.println("son's parentName:"+son.getParentName()+" son's parentAge:"+son.getParentAge()+" son's sonName:"+son.getSonName()+" son's sonAge:"+son.getSonAge());

运行结果:

son's parentName:myParent son's parentAge:50 son's sonName:myName son's sonAge:22

最后我们测试一个构造方法,四个参数:

public class ContextTest {
    private String str;
    private Person person;
    private int id;
    private List list;
    public String getStr() {
        return str;
    }
    public List getList() {
        return list;
    }
    public void setList(List<Integer> list) {
        this.list = list;
    }
    public Person getPerson() {
        return person;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    //三个构造参数,拿来构造注入使用,因此这个bean省略了setter
    ContextTest(String str,Person person,int id,List list)
    {
        this.str = str;
        this.person = person;
        this.id = id;
        this.list = list;
    }
}

容器中的定义:

<!-- 四个构造参数的ContextText -->
    <bean id="context1" class="dao.ContextTest">
        <constructor-arg index="0" value="contextStr" />
        <constructor-arg index="1" ref="Person1" />
        <!-- 这里可以用index指定参数位置,从0开始,也可以用名字出指定构造参数的名字 -->
        <constructor-arg name="id" value="10" />
        <constructor-arg index="3" >
            <list>
                <value>3</value>
                <value>4</value>
                <value>5</value>
            </list>
        </constructor-arg>
    </bean>
//测试多个构造方法的bean  ContextTest
        ContextTest c = (ContextTest)context.getBean("context1");
        System.out.println("第一个构造参数str:"+c.getStr()+" 第二个构造参数person parentName,age依次为:"+c.getPerson().getName()+" "+c.getPerson().getAge()+" 第三构造参数id为:"+c.getId()+" 第四个构造参数list为"+c.getList());

运行结果:

第一个构造参数str:contextStr 第二个构造参数person parentName,age依次为:micro 1 第三构造参数id为:10 第四个构造参数list[3, 4, 5]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值