Spring IOC基础
代码需满足一个高内聚低耦合的原则,以下列示例为例
public interface UserDao {
public void getUser();
}
public class UserDaoImp implements UserDao{
@Override
public void getUser() {
System.out.println(this.getClass().getName()+"获取用户数据");
}
}
public interface UserService {
public void getUser();
}
public class UserServiceImp implements UserService{
UserDao userDao = new UserDaoImp(); //UserServiceImp 依赖于UserDao
@Override
public void getUser() {
userDao.getUser();
}
}
public class Test {
@org.junit.Test
public void test(){
UserService userService = new UserServiceImp();
userService.getUser(); //进行测试
}
}
//输出:com.jojo.UserDaoImp获取用户数据
如果给UserDao新增一个实现类
public class UserDaoMysqlImp implements UserDao{
@Override
public void getUser() {
System.out.println(this.getClass().getName()+"使用mysql获取用户数据");
}
}
这时,如果想要使用UserDaoMysqlImp ,就必须去修改UserServiceImp中的代码
public class UserServiceImp implements UserService{
UserDao userDao = new UserDaoMysqlImp();
@Override
public void getUser() {
userDao.getUser();
}
}
//测试一下
//结果:com.jojo.UserDaoMysqlImp使用mysql获取用户数据
每一次新增Dao的实现类,都需要去修改service的实现类,这样改动太大,耦合性太高
那我们该如何去解决呢?
我们可以对需要的依赖进行set注入,当我们需要什么样的dao,就使用什么样的dao
public class UserServiceImp implements UserService{
UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
大家发现了区别没有 ? 可能很多人说没啥区别 . 但是实际上 , 他们已经发生了根本性的变化 , 很多地方都不一样了 . 仔细去思考一下 , 以前所有东西都是由程序去进行控制创建 , 而现在是由我们自行控制创建对象 , 把主动权交给了调用者 . 程序不用去管怎么创建,怎么实现了 . 它只负责提供一个接口
这种思想也是IOC的原型
控制反转IoC(Inversion of Control),是一种设计思想,**DI(依赖注入)**是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。
没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方。
引用大佬的理解,想要明确什么是IOC,需要侧重于以下几点
- 谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
- 为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。
以图例来说明,传统java程序都是主动去创建对象,然后组合起来
当使用IOC容器后,类的创建递交给了IOC容器,不需要去客户端创建类后再组合