目录
1.理解控制反转、依赖注入的控制和依赖
2.IoC控制反转
3.依赖注入和依赖查找
4.IoC、DI的关系
5.理解Core、Beans、Context
6.IoC注入方式
【控制】和【依赖】都代表对象之间的关联关系,而且他们在Spring中是一对近义词,控制和依赖几乎是并存的。
例如,现有如下需求:汽车的功能是行驶,司机的功能是驾驶汽车,令汽车行驶。
我们可以通过代码描述上述关系:
public class Car { // 汽车类 public void run(){ // 汽车行驶方法 System.out.println("Car : I'm running!"); } } public class Driver { // 司机类 public Car car; public void drive() { // 司机驾驶方法 car.run(); } }上述案例中,司机可以调用驾驶方法,令其包含的汽车对象执行行驶方法。需要关注的问题是,car对象是如何被实例化的。
在传统的Java编程中,我们习惯于将这个car对象通过new的方式创建出来。那么什么时候去new它呢?答案是不唯一的。例如:
1)声明的同时实例化 public class Driver { Car car = new Car(); public void drive(){ car.run(); } } 2)在调用时进行实例化 public class Driver { Car car; public void drive(){ car = new Car(); car.run(); } }上述两种方式,Car对象被创建的时机不同。但是相同的是,new Car()的过程都发生在Driver类中。这样的形式,我们称之为Driver在自己的【代码内部】,控制了一个Car。
注意,这里的【控制】强调的是控制Car对象的创建,而并非Car对象方法的调用。
而【依赖】是指,此时Driver的正常工作需要依赖于Car。换言之,Driver和Car产生了耦合。
IoC即Inversion of Control,控制反转。
可以理解为“反转”对象的控制关系,或“改变”对象的控制关系。
传统的Java SE编程中,对象之间的关系是在【对象内部】直接控制,而IoC正是改变了这样的控制关系,改为由【外部容器】来控制。
大致的过程是,我们不再像原来那样将new操作写死在类中,而是将对象之间的关联关系定义在一个xml配置文件中。在程序运行期间,再由容器根据配置文件中定义的规则管理对象的生命周期,并建立对象之间的关联关系。
假设现在需要使用A对象,A对象中需要配置一个B对象。那么我们在容器中配置一个A对象,配置一个B对象,并声明B对象是A对象的一个属性。这个过程叫做依赖注入。
如果你想从容器中取出某个对象对其进行操作,可以调用context组件的相关方法,根据特定的方式获取容器中的Bean。这个过程叫做依赖查找。
IoC是一种思想,而DI和DL是实现这种思想具体的方式。
从实际角度出发分析,IoC解决了对象由谁来创建、对象之间存在何种关联关系的问题
而DI解决了对象之间的关联关系如何建立的问题
Spring中包含诸多组件,其中Core、Beans、Context是最核心的三个组件。
它们组合起来,就实现了Spring中最核心的功能——IoC。
Beans:组件
Context:容器(用来包含组件) Core:工具
Bean之于Spring相当于Object之于OOP。在Spring中,所有的Java对象都是Bean。
IoC的核心概念是将Bean配置到容器中,而这个容器就是由Context来充当。在编译阶段,我们以xml文件的方式定义容器配置,声明Bean相关内容。运行期间,Spring会解析xml容器配置文件,将其中的内容封装成一个Context对象。我们可以通过这个Context对象获取到容器中的Bean。
Core是处理容器和Bean的一些工具和方法,如果把Core改称为Util就很好理解了。
如果说Context是一个舞台,那么Bean就是这个舞台上的演员。而Core就是演员演出所用的道具。
【注入】也称装配,即为对象的属性赋值,或者是创建对象之间的关联关系
要求:要注入的属性必须包含对应的set方法。
可以注入的类型:①基本数据类型和String类型 ②对象类型 ③集合类型
方式: 配置<constructor-arg>元素 在Bean类中不需要为属性定义set方法,但是要有相应的构造器。 构造器注入有两种形式 一个是根据参数类型 一个是根据参数位置的下标
不需要手动在bean.xml中定义对象和对象的依赖关系。
而是由容器根据某种特定的规则自动帮我们找到合适的对象并进行注入。
两种方式来判断是否符合要求:
1.通过名字进行判断 byName
2.通过类型进行判断 byType
配置自动装配也有两种方式:
在<beans>中定义属性:autowire="no" 相当于全局配置
在<bean>中定义属性:default-autowire="default" 相当于局部配置
【注意】自动装配仅适用于对象类型