控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫依赖查找(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。-- 百度百科
简单说:把有依赖关系的类放到容器中,解析出这些类的实例,就是依赖注入。目的是实现类的解耦
Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。
下面会用通俗易懂的话为大家解释IOC底层原理和什么是IOC容器。
通常我们要在一个类里边使用另一个类的话,最原始的方法就是需要在类里边去new一个对象的实例,然后通过这个实例去调用方法。像下边这样
public class User { public String name; public void take(){ System.out.println("取走快递"); } } public class ExpressStation { public static void main(String[] args) { User user = new User(); user.take(); } } 举个例子来说就是 用户去快递点取快递 用户 = User 快递点 = ExpressStation类 快递 = User里的take()方法但是这种方式使得两个类之间得耦合度太高了,每次都要新建类的实例,并且当User类的路径变化了之后,ExpressStation里边类的路径也要变化。做Java程序,一向追求高内聚和低耦合。
内聚:每个模块尽可能独立完成自己的功能,不依赖于模块外部的代码。 耦合:模块与模块之间接口的复杂程度,模块之间联系越复杂耦合度越高,牵一发而动全身。后来就出现了一个设计模式叫做工厂模式,来降低程序的耦合度。即新建一个所谓的工厂类来统一管理类。
public class User { public String name; public void take(){ System.out.println("取走快递"); } } //工厂类 public class Courier { public static User getUser(){ return new User(); } } public class ExpressStation { public static void main(String[] args) { // User user = new User(); // user.take(); User user1 = Courier.getUser(); user1.take(); } } 通俗点讲就是在快递点与用户之间有了一个快递员。 User类 = 用户 Courier类 = 快递员 (也就是所谓的工厂类) 快递员统一分配快递 = 工厂类统一管理并分配对象 ExpressStation类 = 快递点这种方式比原始方式耦合度更低,但是会出现一个新的问题就是工厂类Courier和ExpressStation会有耦合,在程序里边不可能让它们完全没有耦合,我们能做的就是把耦合降低到最低。
想要把耦合度降低到最低,我们还需要xml解析和反射,也就是Spring框架里来降低耦合度所用到的方法。
public class Courier { public static User getUser(){ //第一步就是解析xml文件 ApplicationContext context = new ClassPathXmlApplicationContext("/xml/demo.xml"); //第二步,通过解析反射得到相应的对象,也可以直接return反射得到的类 User user = context.getBean("user", User.class); //第三步,可以调用对应类里边的方法, user.take(); } } 为什么说Spring框架里这种方法更加的能降低耦合度? 举个栗子:第二种的工厂模式,一旦User类的路径改变,那么Courier里边所用到的User类的路径也要改变。Spring中的巧妙之处就在于,没有固定的路径,而是动态的去获取类的路径。 class Factory{ public static Goods getGood() { String classValue = class属性值; Class class =Class.forName(classValue);//动态的获取类的路径 return (Goods)class.newInstance();//返回类 } } 通俗来讲工厂模式中快递员知道的是你的固定的地址,假如你现在搬家了,快递员必须先知道的你改变的地址然后去给你送快递。假如你现在留给了快递员一个电话,快递员就能根据你的电话来知道你现在处于什么位置?需要去哪给你送快递,于是,不管你的位置跑到哪,快递员都能动态的获取到你的位置,并将你所需要的快递分发给你。制作不易,还望动动小手点个赞!