Spring依赖注入

Spring两种依赖注入方式

Constructor-based dependency injection :基于构造函数的依赖注入

Setter-based dependency injection :基于设值函数的依赖注入

 

一、Spring 基于构造函数的依赖注入

当容器调用带有一组参数的类构造函数时,基于构造函数的 DI 就完成了,其中每个参数代表一个对其他类的依赖。

通过构造方法注入Bean 的属性值或依赖的对象,它保证了 Bean 实例在实例化后就可以使用。

构造器注入在 <constructor-arg> 元素里声明属性, <constructor-arg> 中没有 name 属性。

1、来看个例子

首先来看,基于构造函数的类。注意:这里需要写有参的构造方法!

public class Constructor implements DIService {

    private String name;

    private int age;

    private String color;

    public Constructor(String name,int age,String color){
        this.name = name;
        this.age = age;
        this.color = color;
    }

    @Override
    public String say() {
        return toString();
    }

    @Override
    public String toString() {
        return "Constructor{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }
}

2、在applicationContext.xml中的配置,这里按构造方法中参数的顺序进行赋值。name+age+color

    <bean id="constructor" class="com.xoyar.spring.service.Constructor">
        <constructor-arg value="constructor注入的名字"></constructor-arg>
        <constructor-arg value="666"></constructor-arg>
        <constructor-arg value="green"></constructor-arg>
    </bean>

 

二、Spring 基于设值函数的依赖注入

当容器调用一个无参的构造函数或一个无参的静态 factory 方法来初始化你的 bean 后,通过容器在你的 bean 上调用设值函数,基于设值函数的 DI 就完成了。

属性注入即通过 setter 方法注入Bean 的属性值或依赖的对象。

属性注入使用 <property> 元素, 使用 name 属性指定 Bean 的属性名称,value 属性或 <value> 子节点指定属性值。

属性注入是实际应用中最常用的注入方式。

1、为每个属性写上set访问器。

package com.xoyar.spring.service;

public class Setter implements DIService {

    private String name;

    private int age;

    private String color;

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String say() {
        return toString();
    }

    @Override
    public String toString() {
        return "Setter{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }
}

2、xml配置

    <!-- 通过setter方式注入的name属性-->
    <bean id="setter" class="com.xoyar.spring.service.Setter">
        <property name="name" value="setter方式注入的名字"></property>
        <property name="age" value="18"></property>
        <property name="color" value="red"></property>
    </bean>

最后我们来测试一下:

  @Test
    public void DITest(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        Setter setter = (Setter) ctx.getBean("setter");
        System.out.println(setter.say());
        Constructor constructor = (Constructor) ctx.getBean("constructor");
        System.out.println(constructor.say());
    }

测试结果为:

Setter{name='setter方式注入的名字', age=18, color='red'}
2018-11-10 17:44:34 DEBUG [main] org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:251) - Returning cached instance of singleton bean 'constructor'
Constructor{name='constructor注入的名字', age=666, color='green'}

二、Spring 注入内部 Beans与ref属性

使用 <property> 元素 ref属性,引入另一个Bean对象,完成Bean之间注入。

     <bean id="bydCar" class="com.xoyar.spring.dao.BydCarDaoImpl">
        <constructor-arg value="比亚迪汽车"></constructor-arg>
        <constructor-arg value="Byd"></constructor-arg>
        <constructor-arg value="200000"></constructor-arg>
    </bean>

    <bean id="user" class="com.xoyar.spring.service.Impl.UserServiceImpl">
        <property name="name" value="小明"></property>
        <!-- 引用外部声明的list-->
        <property name="car" ref="bydCar"></property>
    </bean>

 

三、Spring 注入集合

在<list/>, <set/>, <map/>, 和<props/>元素中,也可以设置值和参数分别对应Java的集合类型List, Set, Map, 和 Properties。

p标签用法:          p:<属性名>="xxx" 引入常量值          p:<属性名>-ref="xxx" 引用其它Bean对象

使用p必须引用p名称空间。改写<property>注入为 p名称空间注入。

    <bean id="user1" class="com.xoyar.spring.service.Impl.UserServiceImpl">
        <property name="name" value="小明"></property>
        <!-- 引用外部声明的list-->
        <property name="cars" ref="cars"></property>
    </bean>
    <!--声明集合类型的bean-->
    <util:list id="cars">
        <ref bean="bydCar"></ref>
        <ref bean="foodCar"></ref>
    </util:list>

使用p标签的写法

<!-- 简化写法-->
    <bean id="user2" class="com.xoyar.spring.service.Impl.UserServiceImpl" p:cars-ref="cars" p:name="小红帽"/>

新建一个Gather类,全面地了解一下所有的集合类的注入方式。

1、新建Gather类,包含基本类型以及集合类型的属性。

package com.xoyar.spring.bean;

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

public class Gather {

    private String strVal;
    private int intVal;
    private List<String> listVal;
    private Set<String> setVal;
    private Map mapVal;

    //所有的getter、setter方法。这里只写了map的以作实例

    public Map getMapVal() {
        return mapVal;
    }

    public void setMapVal(Map mapVal) {
        this.mapVal = mapVal;
    }
}

2、在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" xmlns:p="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <bean id="gather" class="com.xoyar.spring.bean.Gather">
        <property name="strVal" value="I am String"></property>
        <property name="intVal" value="100"></property>
        <property name="listVal">
            <list>
                <value>list1</value>
                <value>list2</value>
                <value>list3</value>
                <value>list4</value>
                <value>list5</value>
            </list>
        </property>
        <property name="setVal">
            <set>
                <value>set1</value>
                <value>set2</value>
                <value>set3</value>
            </set>
        </property>
        <property name="mapVal">
            <map>
                <entry key="k1" value="map1"></entry>
                <entry key="k2" value="map2"></entry>
                <entry key="k3" value="map3"></entry>
                <entry key="k4" value="map4"></entry>
                <entry key="k5" value="map5"></entry>
            </map>
        </property>
    </bean>
</beans>

3、在测试类中测试一下

    @Test
    public void testGather(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-property.xml");
        Gather gather = (Gather) ctx.getBean("gather");
        System.out.println("String : "+gather.getStrVal());
        System.out.println("Int : "+gather.getIntVal());
        System.out.println("List : "+gather.getListVal());
        System.out.println("Set : "+gather.getSetVal());
        System.out.println("Map : "+gather.getMapVal());
    }

4、控制台打印结果如下

String : I am String
Int : 100
List : [list1, list2, list3, list4, list5]
Set : [set1, set2, set3]
Map : {k1=map1, k2=map2, k3=map3, k4=map4, k5=map5}

Spring IOC总结

Spring 的IOC(控制反转)是通过依赖注入(dependency injection)来实现的。

 优点 :

* 大量减少了对象的创建和管理 ,使代码层次更加清晰。

* Spring IOC容器是一个轻量级的容器 ,没有侵入性(不依赖容器的API) ,不需要实现一些特殊接口,这是一个合理设计的基本要求。

* 鼓励我们面向接口编程。

* 减少了代码的耦合,将耦合的部分推到了配置文件中 ,如果他们的关系发生了改变,只需要修改配置文件。

* 提供了aop声明式的服务能力。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值