Spring的依赖注入(DI)

1. 什么是依赖注入

依赖注入(DI): Dependency Injection。就是让spring框架给Bean对象的属性进行赋值. 它是 spring 框架核心 ioc 的具体实现.

  • 我们的程序在编写时, 通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。ioc 解耦只是降低他们的依赖关系,但不会消除。 例如:我们的业务层仍会调用持久层的方法。那这种业务层和持久层的依赖关系, 在使用 spring 之后, 就让 spring 来维护了。
  • 简单的说,依赖注入(DI)就是坐等框架把持久层对象传入业务层,而不用我们自己去获取

2. 使用构造函数方式 注入

顾名思义,就是使用类中的构造函数,给成员变量赋值。

注意,赋值的操作不是我们自己做的,而是通过配置的方式,让 spring 框架来为我们注入。具体代码如下

步骤0: 编写AccountService接口
/**
 * 账户的业务接口
 */
public interface AccountService {
    
    

    /**
     * 模拟保存账户
     */
    public void saveAccount();
}
步骤1: 编写AccountServiceImpl
public class AccountServiceImpl implements AccountService {
    
    

    //依赖注入
    private String name;
    private Integer age;
    private Date birthday;

    public AccountServiceImpl() {
    
    
    }

    public AccountServiceImpl(String name, Integer age, Date birthday) {
    
    
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    @Override
    public void saveAccount() {
    
    
        //调用dao层的保存账户的方法
        System.out.println("name =" + name);
        System.out.println("age =" + age);
        System.out.println("birthday =" + birthday);
    }
}
步骤2: 编写beans.xml

使用构造函数的方式,给pojo中的属性传值
要求:

  • 类中需要提供一个对应参数列表的构造函数。

涉及的标签:

  • constructor-arg

    • 属性:
    index:指定参数在构造函数参数列表的索引位置
    type:指定参数在构造函数中的数据类型
    name:指定参数在构造函数中的名称 用这个找给谁赋值
    
    ========上面三个都是找给谁赋值,下面两个指的是赋什么值的========
    
    value:它能赋的值是基本数据类型和 String 类型
    ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean 
    

编写beans.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.xsd">

    <!--创建一个日期对象-->
    <bean id="myDate" class="java.util.Date"></bean>

    <!--配置service-->
    <bean id="accountService" class="com.service.impl.AccountServiceImpl">
        <!--根据name方式 ,进行构造方法赋值-->
        <constructor-arg name="name" value="迪丽热巴"></constructor-arg>
        <constructor-arg name="age" value="22"></constructor-arg>
        <constructor-arg name="birthday" ref="myDate"></constructor-arg>

        <!--根据index方式, 进行构造方法赋值-->
        <constructor-arg index="0" value="晓明"></constructor-arg>
        <constructor-arg index="1" value="25"></constructor-arg>
        <constructor-arg index="2" ref="myDate"></constructor-arg>

        <!--根据type方式, 进行构造方法赋值-->
        <constructor-arg type="java.lang.String" value="小丽"></constructor-arg>
        <constructor-arg type="java.lang.Integer" value="26"></constructor-arg>
        <constructor-arg type="java.util.Date" ref="myDate"></constructor-arg>

    </bean>
</beans>
步骤3: 测试
public class AccountServiceTest {
    
    

    @Test
    public void saveAccount() {
    
    
        // 通过Spring框架加载XML配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");

        //获取Service对象,调用保存账户方法
        AccountService accountService = (AccountService) applicationContext.getBean("accountService");
        accountService.saveAccount();
    }
}

3. 使用set方法方式 注入

**顾名思义,就是在类中提供需要注入成员的 set 方法。**实际开发中,此种方式用的较多

具体代码如下

步骤1: 编写AccountServiceImpl
public class AccountServiceImpl implements AccountService {
    
    

    //依赖注入
    private String name;
    private Integer age;
    private Date birthday;

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

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

    public void setBirthday(Date birthday) {
    
    
        this.birthday = birthday;
    }

    @Override
    public void saveAccount() {
    
    
        //调用dao层的保存账户的方法
        System.out.println("name =" + name);
        System.out.println("age =" + age);
        System.out.println("birthday =" + birthday);
    }
}
步骤2: 编写beans.xml

通过配置文件给 bean 中的属性传值:使用 set 方法的方式
涉及的标签:

  • property

    • 属性:
    name: 找的是类中 set 方法后面的部分
    value: 给属性赋值是基本数据类型和 string 类型的
    ref: 给属性赋值是其他 bean 类型的
    

    编写beans.xml

<!--创建一个日期对象-->
<bean id="myDate" class="java.util.Date"></bean>

<!--配置service-->
<bean id="accountService" class="com.service.impl.AccountServiceImpl">
    <!--根据set方法方式, 进行依赖注入-->
    <property name="name" value="热巴"/>
    <property name="age" value="26"/>
    <property name="birthday" ref="myDate"/>

</bean>
步骤3: 测试
public class AccontTest {
    
    
    public static void main(String[] args) {
    
    
        //获取ApplicationContext对象, Spring容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        //获取Bean对象
        AccountService accountService = (AccountService) applicationContext.getBean("accountService");
        accountService.saveAccount();
    }
}

4. 注入集合属性

顾名思义,就是给类中的集合成员传值,它用的也是set方法注入的方式,只不过变量的数据类型都是集合。
我们这里介绍注入数组,List,Set,Map,Properties。具体代码如下

步骤1:编写AccountServiceImpl
/**
 * 注入 数组或集合的情况
 */
public class AccountServiceImpl2 implements AccountService {
    
    

    //依赖注入
    private String[] myStrs;
    private List<String> myList;
    private Set<String> mySet;
    private Map<String,String> myMap;
    private Properties myProps;

    @Override
    public void saveAccount() {
    
    
        System.out.println("myStrs ====" + Arrays.toString(myStrs));
        System.out.println("myList ====" + myList);
        System.out.println("mySet ====" + mySet);
        System.out.println("myMap ====" + myMap);
        System.out.println("myProps ====" + myProps);
    }

    public void setMyStrs(String[] myStrs) {
    
    
        this.myStrs = myStrs;
    }

    public void setMyList(List<String> myList) {
    
    
        this.myList = myList;
    }

    public void setMySet(Set<String> mySet) {
    
    
        this.mySet = mySet;
    }

    public void setMyMap(Map<String, String> myMap) {
    
    
        this.myMap = myMap;
    }

    public void setMyProps(Properties myProps) {
    
    
        this.myProps = myProps;
    }
}
步骤2: 编写beans.xml

注入集合数据, 在注入集合数据时,只要结构相同,标签可以互换

  • List 结构的:array,list,set

  • Map 结构的: map,entry; props,prop

<bean id="accountService2" class="com.service.impl.AccountServiceImpl2">
    <!--依赖注入 数组-->
    <property name="myStrs">
        <array>
            <value>JavaSE</value>
            <value>JavaWEB</value>
            <value>SSM</value>
        </array>
    </property>
    <!--依赖注入 list集合-->
    <property name="myList">
        <list>
            <value>JavaSE</value>
            <value>JavaWEB</value>
            <value>JavaWEB</value>
            <value>SSM</value>
        </list>
    </property>
    <!--依赖注入 set集合-->
    <property name="mySet">
        <set>
            <value>JavaSE</value>
            <value>JavaWEB</value>
            <value>JavaWEB</value>
            <value>SSM</value>
        </set>
    </property>
    <!--依赖注入 map集合-->
    <property name="myMap">
        <map>
            <entry key="001" value="JavaSE"></entry>
            <entry key="002" value="JavaWEB"></entry>
            <entry key="002" value="SSM"></entry>
        </map>
    </property>
    <!--依赖注入 properties集合-->
    <property name="myProps">
        <props>
            <prop key="001">JavaSE</prop>
            <prop key="002">JavaWEB</prop>
            <prop key="002">SSM</prop>
        </props>
    </property>
</bean>
步骤3: 测试
public class AccontTest {
    
    
    public static void main(String[] args) {
    
    
        //获取ApplicationContext对象, Spring容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        //获取Bean对象
        AccountService accountService2 = (AccountService) applicationContext.getBean("accountService2");
        accountService2.saveAccount();
    }
}
  • 在List结构的集合数据注入时:
    • array,list,set这三个标签通用,另外注值的value标签内部可以直接写值,也可以使用bean标签配置一个对象,或者用ref标签引用一个已经配合的bean的唯一标识。
  • 在Map结构的集合数据注入时:
    • map标签使用entry子标签实现数据注入,entry标签可以使用keyvalue属性指定存入map中的数据。
    • 使用value-ref属性指定已经配置好的bean的引用。
    • 同时entry标签中也可以使用ref标签,但是不能使用bean标签。
    • property标签不能中不能使用ref或者bean标签引用对象

猜你喜欢

转载自blog.csdn.net/weixin_47785112/article/details/107386510