IOC理论推导
大约 3 分钟Spring全家桶Spring入门
原来的步骤
UserDao.java接口
/**
* @Description TODO
* @Author Administrator
* @Date 2020/12/2 19:01
*/
public interface UserDao {
/**
* 获取用户
*/
void getUser();
}
UserDaoImpl.java实现类
/**
* @Description TODO
* @Author Administrator
* @Date 2020/12/2 19:01
*/
public class UserDaoImpl implements UserDao {
public void getUser() {
System.out.println("默认获取用户的数据");
}
}
UserService.java业务接口
/**
* @Description TODO
* @Author Administrator
* @Date 2020/12/2 19:02
*/
public interface UserService {
/**
* 获取用户
*/
void getUser();
}
UserServiceImpl.java业务实现类
/**
* @Description TODO
* @Author Administrator
* @Date 2020/12/2 19:03
*/
public class UserServiceImpl implements UserService {
/**
* 组合引用调用dao层
*/
UserDao userDao = new UserDaoMySqlImpl();
public void getUser() {
userDao.getUser();
}
}
业务调用
/**
* @Description TODO
* @Author Administrator
* @Date 2020/12/2 19:05
*/
public class MyTest {
public static void main(String[] args) {
/**
* 用户实际调用的业务
* dao层他们不需要接触
*/
UserService service = new UserServiceImpl();
service.getUser();
}
}
测试结果
默认获取用户的数据
Process finished with exit code 0
需求有变动
需要使用MySQL数据库实现。则需要一个UserDao接口的MySQL实现类。并且在UserServiceImpl实现类中修改调用的dao层代码。
UserDaoMySqlImpl.java
/**
* @Description UserDao接口MySQL实现
* @Author Administrator
* @Date 2020/12/2 19:08
*/
public class UserDaoMySqlImpl implements UserDao {
public void getUser() {
System.out.println("MySQL获取数据");
}
}
UserServiceImpl.java实现类中修改
/**
* @Description TODO
* @Author Administrator
* @Date 2020/12/2 19:03
*/
public class UserServiceImpl implements UserService {
/**
* 组合引用调用dao层
*/
// UserDao userDao = new UserDaoImpl(); // 默认实现
UserDao userDao = new UserDaoMySqlImpl();
public void getUser() {
userDao.getUser();
}
}
测试结果
MySQL获取数据
Process finished with exit code 0
缺陷
程序适应不了需求。每次需求变动都需要新增dao层实现类,并且修改service层实现类的调用代码。代码修改太多。当需求变得很频繁时,工作量太大。
改进
在之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求取修改原代码!如果程序代码量十分大,修改一次的代价十分昂贵!
我们在service层的实现类中使用一个set接口实现:
/**
* @Description TODO
* @Author Administrator
* @Date 2020/12/2 19:03
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
/**
* 利用set方法动态实现值的注入
* @param userDao
*/
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void getUser() {
userDao.getUser();
}
}
业务调用:
public static void main(String[] args) {
/**
* 用户实际调用的业务
* dao层他们不需要接触
*/
UserService userService = new UserServiceImpl();
UserDao userDao = new UserDaoMySqlImpl();
((UserServiceImpl) userService).setUserDao(userDao);
userService.getUser();
}
结果
MySQL获取数据
Process finished with exit code 0
把对UserDao的实现选择权交给了用户。service层的代码不用再修改。只需要扩展UserDao接口实现类,以及再业务调用的实现选择调用哪一种实现即可。service层代码不用在修改。
分析
- 之前,是程序主动创建对象!控制权在程序猿手上!
- 使用了set注入后,程序不再具有主动性。而是变成了被动的接收对象。
这种思想,从本质上解决了问题。我们能程序猿不用再去管理对象的创建了。系统的耦合性大大降低。可以更加地专注业务的实现。