一、什么是IOC?
1.概念
IOC—Inversion of Control,即“控制反转”,不是新的技术,而是一种设计思想。Java开发中,IOC意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制;
2.谁控制谁,控制什么
传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IOC是有专门一个容器来创建这些对象,即由IOC容器来控制对象的创建;注意:是IOC 容器控制了对象;主要控制了外部资源获取(不只是对象包括比如文件等)。
3.为何是反转,哪些方面反转了
有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;
为何是反转:因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;
什么反转了:依赖对象的获取被反转了。
4.总结:
说白了就是对象不需要你去new,而是交给IOC帮你创建对象,并且帮助我们建立好了类与类之间的关联关系,我们需要时再去获取。
二、什么是DI?
实际上DI和IOC是同一个概念,因为在ApplicationContext.xml配置文件中bean和bean之间通过ref来维护的时候是相互依赖的,所以又叫做依赖注入。也就是控制反转。
三、实例
我们通过一个实例加深Spring IOC&DI的理解:
1.传统的Java程序,这里建立两个实体的关联关系:
public class A{ public void show(){ System.out.println("A show()..."); } } public class B{ private A a; public void show(A a){ a.show(); } } public class Main{ public static void main(String[] args){ A a = new A(); B b = new B(); b.show(a); } }
从上方代码看出,我们如果使用组合,那么使用起来必然是比较麻烦,不仅需要创建B对象,而且还需要创建A对象,然后再将A对象传给B的方法,再调用show方法。
然而,使用spring后,只需要在IOC容器中配置两个的关联,在测试方法中,直接B b = new B();这时A自动就被创建,并且包含在B中,而无需我们再去创建A对象,节省了很多操作,我们来看看创建了IOC容器对象后,IOC容器帮我们做了哪些工作:
首先创建两个Bean,分别是Parent和Child:
public class Parent { private Child child; public void setChild(Child child) { this.child = child; } public Child getChild() { return child; } public Parent(){ System.out.println("Parent Constructor..."); } }
public class Child { public Child(){ System.out.println("Child Constructor..."); } }
接着,在applicationContext.xml中配置以上两个Bean以及引用关系:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="child" class="com.spring.model.Child"></bean> <bean id="parent" class="com.spring.model.Parent"> <property name="child" ref="child"></property> </bean> </beans>
最后,测试程序:
public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); } }
执行后,输出:
Child Constructor...
Parent Constructor...
说明:只要Bean配置到IOC容器中,IOC容器会通过配置在其里面的Bean的全限定名以反射的方式通过无参构造器创建Bean的实例。
由于IOC容器内已配置关联关系,所以我们在测试程序中获取Bean:
public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); Parent parent = ctx.getBean(Parent.class); System.out.println("parent=" + parent); System.out.println("child=" + parent.getChild()); } }
执行后,输出结果:
Child Constructor... Parent Constructor... parent=[email protected] child[email protected]
四、总结
Bean实例化和Bean与Bean之间的依赖关系交给IOC容器帮我们实例化,我们需要时再去获取。
PS:光看概念也许不太容易理解,自己动手,会更明白 !