Spring中的IoC是一种思想。所谓控制反转,也就是从创建对象的主动权在程序员手中,到创建对象的主动权在用户手中。控制反转官方定义是一种通过描述(XML或注解)并通过第三方生产或获取特定对象的方式,在Spring中实现控制反转的是IoC容器,其实现方式是依赖注入(Dependence Injection,DI)。
我在这里以代码和需求的形势进行阐述
首先我在Dao层写一个UserDao的接口里面有一个方法
package com.zhiying.dao;
public interface UserDao {
    public void getUser();
}
然后写一个UserDaoImpl的类来实现这个接口,并输出一句话
package com.zhiying.dao;
public class UserDaoImpl implements UserDao {
    public void getUser() {
        System.out.println("this is a user");
    }
}
现在我们开始写Service层,这里写一个UserService的接口,并定义一个方法
package com.zhiying.service;
public interface UserService {
    public void getUser();
}
然后写一个UserServiceImpl的实现类
package com.zhiying.service;
import com.zhiying.dao.UserDao;
import com.zhiying.dao.UserDaoImpl;
public class UserServiceImpl implements UserService {
    UserDao userDao = new UserDaoImpl();
    public void getUser() {
        userDao.getUser();
    }
}
下面开始测试:
import com.zhiying.service.UserService;
import com.zhiying.service.UserServiceImpl;
public class MyTest {
    public static void main(String[] args) {
        UserService userService= new UserServiceImpl();
        userService.getUser();
    }
}
测试结果如下,也正是我们所料

但如果我们想要不同的用户去实现该接口呢,例如我们要Mysql用户去实现
package com.zhiying.dao;
public class UserDaoMysqlImpl implements UserDao {
    public void getUser() {
        System.out.println("this is a mysql");
    }
}
这时候我们就需要去修改Service层的方法,结果如下
package com.zhiying.service;
import com.zhiying.dao.UserDao;
import com.zhiying.dao.UserDaoImpl;
import com.zhiying.dao.UserDaoMysqlImpl;
public class UserServiceImpl implements UserService {
    //UserDao userDao = new UserDaoImpl();
    UserDao userDao = new UserDaoMysqlImpl();
    public void getUser() {
        userDao.getUser();
    }
}
然后测试结果如下:

虽然得到了我们想要的结果,但是这里需要改Service层的代码,很不好,所以就有了面向切面编程的IOC思想,用一个set注入
把UserService接口和UserServiceImpl类改为如下
package com.zhiying.service;
import com.zhiying.dao.UserDao;
public interface UserService {
    public void setUserDao(UserDao userDao);
    public void getUser();
}
package com.zhiying.service;
import com.zhiying.dao.UserDao;
import com.zhiying.dao.UserDaoImpl;
import com.zhiying.dao.UserDaoMysqlImpl;
public class UserServiceImpl implements UserService {
    //UserDao userDao = new UserDaoImpl();
    //UserDao userDao = new UserDaoMysqlImpl();
    UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void getUser() {
        userDao.getUser();
    }
}
这时候,把测试类也需要修改,这时候的主动权就在用户手中了,用户可以自定义的调用
import com.zhiying.dao.UserDaoImpl;
import com.zhiying.dao.UserDaoMysqlImpl;
import com.zhiying.service.UserService;
import com.zhiying.service.UserServiceImpl;
public class MyTest {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        userService.setUserDao(new UserDaoMysqlImpl());
        userService.getUser();
        userService.setUserDao(new UserDaoImpl());
        userService.getUser();
    }
}

这样就实现了,添加新的UserDao实现,也不用改Service层的代码了,而且想实现谁用户可以自定义。
来源:CSDN
作者:贺志营
链接:https://blog.csdn.net/HeZhiYing_/article/details/103927943