首页 > 编程语言 > 详细

Spring中的依赖注入2

时间:2020-04-30 21:35:35      阅读:53      评论:0      收藏:0      [点我收藏+]

一、背景

实现控制反转(Ioc)的方式有很多种,依赖注入(DI)是实现控制反转的一种方法.

1.有数据层dao包和服务层service包

分别在其中定义了相应的接口.
技术分享图片

1.1接口UserDao

在UserDao接口中定义了一个getUserName方法

package dao;

/**
 * @Author Yiang37
 * @Date 2020/4/30 20:16
 * Description:
 */
public interface UserDao {

    void getUserName();
}

它有两个实现类UserDaoImplByMysql与UserDaoImplByOracle
技术分享图片
UserDaoImplByMysql代码如下

package dao.impl;

import dao.UserDao;

/**
 * @Class: UserDaoImplByMysql
 * @Author: Yiang37
 * @Date: 2020/4/30 20:19
 * @Description:
 */

public class UserDaoImplByMysql implements UserDao {

    public void getUserName() {
        System.out.println("我是Mysql的getUserName");
    }
}

UserDaoImplByOracle代码如下

package dao.impl;

import dao.UserDao;

/**
 * @Class: UserDaoImpl
 * @Author: Yiang37
 * @Date: 2020/4/30 20:17
 * @Description:
 */
public class UserDaoImplByOracle implements UserDao {
    public void getUserName() {
        System.out.println("我是Oracle的getUserName");
    }
}

1.2接口UserService

在UserService接口中定义了一个outUserName()方法

package service;

/**
 * @Class: UserService
 * @Author: Yiang37
 * @Date: 2020/4/30 20:21
 * @Description:
 */
public interface UserService {
    void outUserName();
}

它有一个实现类UserServiceImpl
技术分享图片
UserServiceImpl代码如下

package service.impl;

import dao.UserDao;
import dao.impl.UserDaoImplByMysql;
import service.UserService;

/**
 * @Class: UserService
 * @Author: Yiang37
 * @Date: 2020/4/30 20:21
 * @Description:
 */
public class UserServiceImpl implements UserService {
    
    UserDao userDao = new UserDaoImplByMysql();

    public void outUserName() {
        userDao.getUserName();
    }
}

2.使用service完成操作

import service.UserService;
import service.impl.UserServiceImpl;

/**
 * @Class: Test1
 * @Author: Yiang37
 * @Date: 2020/4/30 20:23
 * @Description:
 */
public class Test1 {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        userService.outUserName();
    }
}  

可以看到程序输出

我是Mysql的getUserName

二、分析

1.修改显示的值

在上面的内容中我们看到userService.outUserName()在执行后输出了

我是Mysql的getUserName

为什么会是这个结果?这还得回到UserServiceImpl的代码中

1. public class UserServiceImpl implements UserService {
2.    
3.    UserDao userDao = new UserDaoImplByMysql();
4.
5.    public void outUserName() {
6.        userDao.getUserName();
7.    }
8.  }

我们看到在代码的第6行调用了userDao.getUserName();
而这个userDao是谁呢?
在代码的第3行指定了

 UserDao userDao = new UserDaoImplByMysql();

现在问题来了,我们想修改为UserDaoImplByOracle()来实现?
可以更改上面userDao的具体实现类

 UserDao userDao = new UserDaoImplByOracle();

程序输出了我们想要的结果

我是Oracle的getUserName

通过上面的方式,虽然能达到结果,但是我们得修改掉原来的代码
在调用userDao时,我们就得明确的指明它的实现类.

2.改进

我们是否可以每次为userService动态的指定其中的userDao呢?
修改我们的代码,变成下面这样.

public class UserServiceImpl implements UserService {
    //成员变量UserDao
    private UserDao userDao;

    //UserDao属性的set方法
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void outUserName() {
        userDao.getUserName();
    }
}

现在我们再修改测试类

public class Test1 {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        ((UserServiceImpl)userService).setUserDao(new UserDaoImplByMysql());
        userService.outUserName();
    }
}

注:
UserService userService = new UserServiceImpl();
左侧是UserService类型,是找不到setUserDao()方法的.
所以在setUserDao()方法之前进行了类型转换.
( (UserServiceImpl) userService).xx

技术分享图片

当创建时指明类型为UserServiceImpl时才有这个方法
"多态相关知识"
技术分享图片

现在我们通过set方法为其注入了UserDaoImplByMysql对象,再次运行.

我是Mysql的getUserName

为其set进不同的值,例如.

((UserServiceImpl)userService).setUserDao(new UserDaoImplByOracle());

同样能成功输出想要的内容

我是Oracle的getUserName

三、对比

一开始是程序主动设置userDao对象,现在变成了程序被动的接收userDao对象.
我们可以看到,通过后者,无需更改UserServiceImpl中的任何内容.
只是在使用通过set注入,即可实现想要的效果.

当写了新的userDao时,例如.

public class UserDaoImplBySqlServer implements UserDao {
    public void getUserName() {
        System.out.println("我是SqlServer的getUserName");
    }
}

然后在使用时set进不同的内容
技术分享图片

((UserServiceImpl)userService).setUserDao(new UserDaoImplBySqlServer());

输出值即可改变

我是SqlServer的getUserName

通过上面的方式,写代码时不用再去管理对象的创建了.
例如UserServiceImpl中的userDao对象我们不用显示的指明,而是可以从外部动态的(被动的)接收.

控制反转,现在是不是反转了,这就是Ioc的原型.

四、Spring中的Ioc

Spring中的依赖注入2

原文:https://www.cnblogs.com/yang37/p/12811265.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!