Spring配置文件依赖注入

Bean的依赖注入分析

之前学的都是对Dao层的数据在Spring容器中的操作,然而在实际开发当中,除了Dao层,还有业务层和web层(就是controller层)也需要在Spring容器中操作。因为controller层中需要调用service层,而service层中又需要dao层数据。所以自然而然地,我们想到在Spring容器中写上两个bean,一个service层的bean,一个dao层的bean。
但是分析后可以知道,这样的做法其实是在容器外部获得UserService(即业务层)实例和UserDao实例(即Dao层)。
在这里插入图片描述
而我们的web层只需要调用service层就可以实现需要的操作,至于service层是如何调用dao层的,我们可以不用管理,这十分符合SpringIoc控制反转的理念,所以这里可以使用Spring依赖注入的方式,在Spring容器中将dao层实例注入service层中,而不用在程序中进行结合。
在这里插入图片描述

Bean的依赖注入概念

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

Bean依赖注入的两种方式

1、set方法注入
2、构造器方式注入

Bean依赖注入之set方法注入

由上面的概述,我们现在来实操。
首先原来的UserServiceImpl类中因为需要调用dao层中UserDao的方法,所以原来是这么写的

package com.itheima.service.impl;

import com.itheima.dao.UserDao;
import com.itheima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceImpl implements UserService {
    public void save() {
        //寻找Spring的配置文件
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //id就是这里的Spring容器要创建的哪个bean对象的标识
        UserDao userDao1 = (UserDao) app.getBean("userDao");
        userDao1.save();
    }
}

而现在因为Spring容器依赖注入了,那么上面save中的繁复操作就不再需要了。
变成这样:

package com.itheima.service.impl;

import com.itheima.dao.UserDao;
import com.itheima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceImpl implements UserService {


    /*设置一个UserDao类型的变量userDao,我们不需要赋给它值
    因为在Spring内部中这个userDao(就是对应的id值)已经被Spring通过set方法
    注入到了UserServiceImpl中,所以这个userDao是有值的
    (之前想不明白的这里终于解决了(暴风哭泣))
     */
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void save() {
        /*
        因为Dao层的userDao已经由Spring容器帮忙创建注入service层了,
        所以下面这一段userDao的创建就不再需要了
         */
//        //寻找Spring的配置文件
//        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//        //id就是这里的Spring容器要创建的哪个bean对象的标识
//        UserDao userDao = (UserDao) app.getBean("userDao");
        userDao.save();
    }
}

接下来要去配置文件中告诉Spring容器将dao实例依赖注入:

<?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">

    <!--创建dao层的userDao实例-->
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>

    <!--创建userService层的userService实例-->
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
        <!--这个name要注意,它指的不是上面dao层的id值userDao
        而是set方法名中除去set三个字母后后面剩下的字符串,且开头小写
        (因为是set方法注入嘛)
        如UserServiceImpl中的set方法为setUserDao,所以这里的name就是:userDao
        -->
        <!--对象的引用用ref
        这里UserService对象通过id标识引用bean创建的dao对象,且因为dao对象中使用了set方法,而set方法中便设置了userDao的值,所以完成了依赖注入
        总结起来就是,Java程序代码实现方式转换成了Spring容器中的代码实现方式而已
        -->
        <property name="userDao" ref="userDao"></property>
    </bean>

</beans>

Bean依赖注入之构造器方法注入

大体流程和上面差不多

package com.itheima.service.impl;

import com.itheima.dao.UserDao;
import com.itheima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceImpl implements UserService {


    /*设置一个UserDao类型的变量userDao,我们不需要赋给它值
    因为在Spring内部中这个userDao(就是对应的id值)已经被Spring通过有参构造方法
    注入到了UserServiceImpl中,所以这个userDao是有值的
    (之前想不明白的这里终于解决了(暴风哭泣))
     */
    private UserDao userDao;

    //设置有参构造器,将userDao注入UserServiceImpl中
    public UserServiceImpl (UserDao userDao){
        this.userDao = userDao;
    }
    //通常写了有参构造器也会将无参构造器写上,防止某些地方报错
    public UserServiceImpl(){
        
    }

    public void save() {
        /*
        因为Dao层的userDao已经由Spring容器帮忙创建注入service层了,
        所以下面这一段userDao的创建就不再需要了
         */
//        //寻找Spring的配置文件
//        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//        //id就是这里的Spring容器要创建的哪个bean对象的标识
//        UserDao userDao = (UserDao) app.getBean("userDao");
        userDao.save();
    }
}

然后在Spring配置文件中写上:

<?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">



    <!--id叫什么名儿都行,然后后面的class跟上全类名-->

    <!--创建dao层的userDao实例-->
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>

    <!--创建userService层的userService实例-->
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
        <!--这个name要注意,它指的不是上面dao层的id值userDao
        而是有参构造器中传入的形参名
        -->
        <!--然后因为是有参构造器实现依赖注入,所以用constructor-arg标签注入
        对象的引用用ref-->
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    </bean>

</beans>

Bean的依赖注入的数据类型

上面的操作,都是注入的引用Bean,除了对象的引用可以注入外,普通数据类型,集合等都可以在容器中注入。
注入数据的三种类型:
1、普通数据类型
2、引用数据类型(就是上面的bean引入)
3、集合数据类型

普通数据类型引入代码演示

在UserDaoImpl中写上:

package com.itheima.dao.impl;

import com.itheima.dao.UserDao;

public class UserDaoImpl implements UserDao {
    
    //为了演示普通数据类型引入
    //声明两个普通数据
    //这里就暂且使用set方法注入演示,而且一般是set方法注入
   private String username;
   private int age;
    
//我们在save方法中测试username和age是否有注入
    public void save() {
        System.out.println(username+"=="+age);
        System.out.println("save running...");
    }
}

然后在Spring配置文件中注入:

<?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">


<!--创建userDao实例-->
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
        <!--给普通数据类型赋值用value,ref是给引用对象类型用的-->
        <property name="username" value="zhangsan"></property>
        <property name="age" value="22"></property>
    </bean>

</beans>

集合数据类型引入代码演示

一样的,在UserDaoImpl中:

package com.itheima.dao.impl;

import com.itheima.dao.UserDao;
import com.itheima.domain.User;

import java.util.List;
import java.util.Map;
import java.util.Properties;

public class UserDaoImpl implements UserDao {

    //为了演示集合数据类型引入
    //声明几个集合数据
    private List<String> stringList;
    private Map<String,User> userMap;
    private Properties properties;

    public void setStringList(List<String> stringList) {
        this.stringList = stringList;
    }

    public void setUserMap(Map<String, User> userMap) {
        this.userMap = userMap;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    //为了演示普通数据类型引入
    //声明两个普通数据
    //这里就暂且使用set方法注入演示,而且一般是set方法注入
   private String username;
   private int age;

    public void setUsername(String username) {
        this.username = username;
    }

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

    //我们在save方法中测试username和age还有集合数据是否有注入
    public void save() {
//        System.out.println(username+"=="+age);
        System.out.println(stringList);
        System.out.println(userMap);
        System.out.println(properties);
        System.out.println("save running...");
    }
}

然后改配置文件

<?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">


    <!--创建userDao实例-->
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
        <!--这几个一般够用了,还有其他的其实都很类似,自己可以举一反三的-->
        <!--注入List-->
        <property name="stringList">
            <list>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
            </list>
        </property>
        <!--注入Map-->
        <property name="userMap">
            <map>
                <!--这里要使用引用类型User,所以要在Spring容器中
                配置上User的bean实例
                -->
                <entry key="user1" value-ref="user1"></entry>
                <entry key="user2" value-ref="user2"></entry>
            </map>
        </property>
        <!--注入Properties-->
        <property name="properties">
            <props>
                <!--这个稍微特殊点,记住格式就行了-->
                <prop key="p1">ppp1</prop>
                <prop key="p2">ppp2</prop>
                <prop key="p3">ppp3</prop>
            </props>
        </property>
    </bean>

    <!--配置的User类型的实例-->
    <bean id="user1" class="com.itheima.domain.User">
        <property name="name" value="tom"></property>
        <property name="addr" value="beijing"></property>
    </bean>
    <bean id="user2" class="com.itheima.domain.User">
        <property name="name" value="lucy"></property>
        <property name="addr" value="shanghai"></property>
    </bean>

</beans>

Spring引入其他配置文件(分模块开发)

实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,不易阅读也不易后期维护。所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件中通过import标签进行加载。
<import>标签:导入其他的Spring的分文件。

<import resource=“applicationContext-xxx.xml”>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在地球迷路的怪兽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值