Version: Next
IoC控制翻转
2. IoC控制反转
2.1 IoC理论推导
原思路:
UserDao接口
public interface UserDao {void getUser();}UserDaoImpl实现类
public class UserDaoImpl implements UserDao {public void getUser() {System.out.println("默认获取用户的数据");}}UserService业务接口
public interface UserService {void getUser();}UserServiceImpl业务实现类
public class UserServiceImpl implements UserService {//组合private UserDao userDao = new UserDaoImpl();public void getUser() {userDao.getUser();}}
warning
当来了新需求,写了新的dao层impl类,在Service层组合部分,必须new新的dao层impl类
必须修改原有代码,没有做到对修改关闭,对扩展开放(开闭原则)
- 利用接口多态性解决:
新UserDao实现类
public class UserDaoMysqlImpl implements UserDao{public void getUser() {System.out.println("mysql获取用户数据");}}修改UserServiceImpl
public class UserServiceImpl implements UserService {//组合//private UserDao userDao = new UserDaoXxxImpl();private UserDao userDao;public void getUser() {userDao.getUser();}//利用多态性,set注入public void setUserDao(UserDao userDao) {this.userDao = userDao;}}使用时
@Testpublic void testTraditional(){//用户实际调用的是业务层,dao层不需要被用户接触UserService userService = new UserServiceImpl();((UserServiceImpl) userService).setUserDao(new UserDaoImpl());userService.getUser();((UserServiceImpl) userService).setUserDao(new UserDaoMysqlImpl());userService.getUser();}
warning
在之前的业务中,用户的需求可能会影响原来的代码。因为我们需要根据用户的需求修改源代码。代码量十分大,修改一次代价昂贵
使用一个set接口方法实现,已经发生了革命性的变化。符合了开闭原则
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
- 之前:程序是主动创建对象,控制权在程序员手上
- 之后:使用了set注入后,程序不再具有主动性,而是被动接收对象
这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建了。系统耦合性降低,可以更加专注于业务实现,业务受客户的需求控制,不受随程序员的代码束缚。(IoC控制反转)
info
获取依赖对象的方式反转了,Spring底层大量使用这种方式,因此没有set方法的话是跑不起来的,DI依赖注入是IoC的实现方式之一
2.2 IoC的本质
IoC是Spring框架的核心内容。可以使用多种方式实现,xml、注解或自动装配
Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时从IoC容器中取出需要的对象
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器。其实现方法是依赖注入DI(Dependency Injection)