** 控制反转loC(Inversion of Control),是-种设计思想,DI(依赖注入)是实现IoC的一种方法**
首先说一下思想:控制反转是将创建对象的权限从程序员交给用户。
举例说明:
//创建一个UserDao接口
public interface UserDao {
public void getUser();
}
//实现类
public class UserDaoImpl implements UserDao{
@Override
public void getUser() {
System.out.println("获取用户数据");
}
}
在用Services实现
public interface UserService {
void getUser();
}
public class UserServiceImpl implements UserService{
private UserDao userDao = new UserDaoImpl();
@Override
public void getUser() {
userDao.getUser();
}
}
//测试代码
public class MyTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.getUser();
}
}
输出 结果
假如用户需求变了,要求我们调用MySQL里的数据,我们还像上边的方式,再创建一个UserDaoMysqlImpl实现类(这个是每次都要创建的)。
public class UserDaoMysqlImpl implements UserDao{
@Override
public void getUser() {
System.out.println("获取用户MySQL数据");
}
}
相对应Service实现类也要发生变化
public class UserServiceImpl implements UserService{
//private UserDao userDao = new UserDaoImpl();
//
private UserDao userDao = new UserDaoMysqlImpl();
@Override
public void getUser() {
userDao.getUser();
}
}
那么问题来了
如果用户再次要求调用oracle用户数据等类似操作的话,总不能每次都有程序员修改这里的代码(这只是个代码例子,代码量比较少,若是几百行甚至更多的话,会更加繁琐),这就是创建对象的权限在程序员身上的弊端。
控制反转就是将创建对象的权限转交给用户。利用这一点,可以将代码优化为
public class UserServiceImpl implements UserService{
//private UserDao userDao = new UserDaoImpl();
//private UserDao userDao = new UserDaoMysqlImpl();
private UserDao userDao;
//利用有参构造器实现动态注入
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
此时,只需要在测试类中根据用户需求选择相应的实现类
public class MyTest {
public static void main(String[] args) {
//UserService userService = new UserServiceImpl();之前的
UserService userService = new UserServiceImpl(new UserDaoMysqlImpl());
userService.getUser();
}
}
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的.
反转:程序本身不创建对象,而变成被动的接收对象.