Spring学习笔记(三) : 配置文件_依赖注入

192 阅读4分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路

需要用到的dao接口和实现类

Userdao接口

package com.dao;

public interface UserDao {
    public void save();
}

UserDaoImpl 实现类

package com.dao.impl;

import com.dao.UserDao;

public class UserDaoImpl implements UserDao {//实现UserDao接口


    public UserDaoImpl() {
        System.out.println("UserDaoImpl创建.....");
    }

    public void init(){
        System.out.println("初始化方法......");
    }
    public void destory(){
        System.out.println("销毁方法......");
    }

    public void save() {//实现UserDao接口下的save方法
        System.out.println("save running.....");
    }
}



Service相关的接口和类

创建一个接口UserService

package com.service;

public interface UserService {
    public void save();
}

创建一个接口实现类UserServiceImpl, 实现接口 UserService

package com.service.impl;

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

public class UserServiceImpl implements UserService {
    public void save() {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) app.getBean("userDao");//参数是id的名字
        userDao.save();
    }
}


创建一个测试类

package com.demo;

import com.service.UserService;
import com.service.impl.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserController {
    public static void main(String[] args) {
        //内部要获取Service
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) app.getBean("userService");
        userService.save();

    }
}

把UserService也配置到容器当中, 打开applicationContext.xml

<bean id="userDao" class="com.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.service.impl.UserServiceImpl"></bean>

测试结果 在这里插入图片描述

存在问题

目前UserService实例和UserDao实例都存在Spring容器中, 当前的做法是在容器外步=部获得UserService实例和UserDao实例, 然后在程序中结合

getBean(name:"userService") 获得UserService实例, 发现UserService实例内部需要UserDao实例的save()方法, 所以在UserService内部获取UserDao实例

getBean(name:"userDao") 相当于是在Spring容器外将Dao组装到Service内部完成的操作

改进

因为UserService实例和UserDao实例都存在Spring容器中, 而最终程序直接使用User Service, 所以可以在Spring容器内, 将UserDao设置到UserService的内部

在这里插入图片描述 所以, 怎么把一个对象放到另一个对象的内部呢?

Bean的依赖注入分析

依赖注入: Spring核心框架IOC的具体体现

在编写程序时, 通过控制反转, 把对象的创建交给了Spring , 但代码中不可能出现没有依赖的情况, IOC解耦只是降低他们的依赖关系, 但不会消除.

那种业务层与持久层的关系, 在使用Spring后, 就让Spring来维护 简单地说, 就是坐等框架把持久层对象传入业务层, 而不用我们自己取获取

所以, 梅开二度,怎么把一个对象放到另一个对象的内部呢?可以使用构造方法和set方法

Spring的applicationContext配置 把容器当中的UserDao通过userService的setUserDao的方法来配置

	<bean id="userDao" class="com.dao.impl.UserDaoImpl"></bean>
    <bean id="userService" class="com.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"></property>
    </bean>

接口UserService的实现类UserServiceImpl改正这样

package com.service.impl;
import com.dao.UserDao;
import com.service.UserService;

public class UserServiceImpl implements UserService {

    private UserDao userDao;

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

    public void save() {

        userDao.save();
    }
}

测试UserCotroller类

在这里插入图片描述

set方法注入

这是一种简便的配置方法

<bean id="userDao" class="com.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.service.impl.UserServiceImpl" p:userDao-ref="userDao"/>

构造方法的注入

给实现类设置有参和无参的构造方法

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    //生成一个构造:有参构造
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }
    //无参构造
    public UserServiceImpl() {
    }
    
    public void save() {

        userDao.save();
    }
}

配置文件

<bean id="userDao" class="com.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.service.impl.UserServiceImpl">
	<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>

Bean的依赖注入的数据类型

上面的操作, 都是注入的引用Bean , 除了对象的引用可以注入, 普通数据类型, 集合等都可以在容器中注入

注入数据的三种类型: 普通数据类型, 引用数据类型, 集合数据类型

注入普通数据类型

UserDaoImpl中修改一下代码

package com.dao.impl;
import com.dao.UserDao;

public class UserDaoImpl implements UserDao {//实现UserDao接口

    private String username;
    private int age;

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

    public void setAge(int age) {
        this.age = age;
    }  
    public void save() {//实现UserDao接口下的save方法
        System.out.println(username+":"+age);
        System.out.println("save running.....");
    }
}

配置文件, 如果时普通数据类型, 在配置文件中的属性不用ref, 用value

	<bean id="userDao" class="com.dao.impl.UserDaoImpl">
        <property name="username" value="zhangsan"/>
        <property name="age" value="18"/>
    </bean>

	<bean id="userService" class="com.service.impl.UserServiceImpl">
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    </bean>

测试

public class UserController {
    public static void main(String[] args) {
        //内部要获取Service
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

结果

在这里插入图片描述 注入成功

集合的注入

创建一个User类作为注入的对象

package com.domain;

public class User {
    private String name;
    private String addr;

    public String getName() {
        return name;
    }

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

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }
}
	@Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", addr='" + addr + '\'' +
                '}';
    }

UserDaoImpl类

public class UserDaoImpl implements UserDao{
	private List<String> strList;
    private Map<String, User> userMap;
    private Properties properties;
	
	public void setStrList(List<String> strList) {
        this.strList = strList;
    }

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

    public void setProperties(Properties properties) {
        this.properties = properties;
    }
	
	public void save() {//实现UserDao接口下的save方法
        System.out.println(strList);
        System.out.println(userMap);
        System.out.println(properties);
        System.out.println("save running.....");
    }
}

配置文件

	<bean id="userDao" class="com.dao.impl.UserDaoImpl">
        <property name="strList">
            <list>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
            </list>
        </property>
        <property name="userMap">
            <map>
                <entry key="u1" value-ref="user1"></entry>
                <entry key="u2" value-ref="user2"></entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="a1">aaa1</prop>
                <prop key="a2">aaa2</prop>
                <prop key="a3">aaa3</prop>
            </props>
        </property>
    </bean>

    <bean id="user1" class="com.domain.User">
        <property name="name" value="zhansan"/>
        <property name="addr" value="guangzhou"/>
    </bean>
    <bean id="user2" class="com.domain.User">
        <property name="name" value="lisi"/>
        <property name="addr" value="shengzhen"/>
    </bean>

	<bean id="userService" class="com.service.impl.UserServiceImpl">
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    </bean>

测试类

package com.demo;

import com.service.UserService;
import com.service.impl.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserController {
    public static void main(String[] args) {
        //内部要获取Service
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

测试结果 在这里插入图片描述