IOC
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
简单的说:IoC就是将对象的创建与对象之间的调用这一过程交给Sping进行管理。Ioc的目的:降低耦合度。而IoC的底层就是通过xml解析、工厂模式、反射结合使用进行解耦操作
解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”
传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建以及外部资源获取(不只是对象包括比如文件等)
IoC具体做什么?
IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。
-
传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;
-
有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
-
IoC对编程实现由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
DI
DI—Dependency Injection,即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
说说你对IOC的理解
IoC是控制反转的意思,是一种面向对象编程的设计思想。在不采用这种思想的情况下,我们需要自己维护对象与对象之间的依赖关系,很容易造成对象之间的耦合度过高,在一个大型的项目中这十分的不利于代码的维护。IoC则可以解决这种问题,它可以帮我们维护对象与对象之间的依赖关系,并且降低对象之间的耦合度。说到IoC就不得不说DI,DI是依赖注入的意思,它是IoC实现的实现方式。由于IoC这个词汇比较抽象而DI比较直观,所以很多时候我们就用DI来代替它,在很多时候我们简单地将IoC和DI划等号,这是一种习惯。IOC 容器实际上就是一个 Map 的键值对,Map 里面存放的是各种对象。实现依赖注入的关键是IoC容器,它的本质就是一个工厂,当我们需要创建对象的时候,只需要通过 xml 配置文件或者注解,把对象注册到组件中,而我们完全不用考虑对象是如何被创建出来的。
IOC原理实战
首先在pom.xml文件中加入spring的相关jar包。
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.0.RELEASE</version></dependency>
</dependencies>
我们定义我们的接口和实现类
// UserDao接口
public interface UserDao {void getUser();
}
// UserDao实现类1,mysql实现
public class UserDaoImpl implements UserDao {public void getUser() {System.out.println("mysql实现");}
}
// UserDao实现类2,oracle实现
public class UserDaoImpl implements UserDao {public void getUser() {System.out.println("oracle实现");}
}
对应的测试类:
public class UserServiceImpl implements UserService {private UserDao userDao;// 利用set进行动态实现值的注入public void setUserDao(UserDao userDao) {this.userDao = userDao;}public void getUser() {userDao.getUser();}
}
如此一来只需要在测试类中通过set方法,传入对应的实现类对象,就可以实现调用不同的实现对象的getUser方法。
public class MyTest {public static void main(String[] args) {// 利用set注入的方法,我们可以不需要修改service中的代码,从而实现多个不同对象的getUser方法UserServiceImpl userService = new UserServiceImpl();userService.setUserDao(new UserDaoImpl());userService.getUser();//mysql实现userService.setUserDao(new UserDaoOracleImpl());userService.getUser();//oracle实现}
}
这两种模式的区别可以发现。之前,控制UserDao实现类的控制权,在程序员手上,程序员写在UserServiceImpl里,写死了对应的是实现类,如果要修改的话,程序员就必须去修改对应的代码。而后面这种方法,控制UserDao实现类的控制权,就已经不在程序员手上了。现在程序是被动接收对象,然后动态set注入实现了可以随意使用不同的实现类的getUser方法。
话,程序员就必须去修改对应的代码。而后面这种方法,控制UserDao实现类的控制权,就已经不在程序员手上了。现在程序是被动接收对象,然后动态set注入实现了可以随意使用不同的实现类的getUser方法。
这其实就是一种控制反转IOC的原型。这种思想从本质上解决了问题,程序员不用再去管理对象的创建了。系统的耦合性大大降低。可以更加专注的在业务的实现上。spring的底层全部都是基于这种思想去实现的。