首先提问: 什么是 Spring IOC 容器?
Spring 框架的核心是 Spring 容器。容器创建对象,将它们装配在一起,配置它们并管理它们的完整生命周期。Spring 容器使用依赖注入来管理组成应用程序的组件。容器通过读取提供的配置元数据来接收对象进行实例化,配置和组装的指令。该元数据可以通过 XML,Java 注解或 Java 代码提供。
然而,依赖注入到底是什么?
依赖注入(Dependency Injection):两个对象之间的依赖关系在程序运行时由外部容器动态的注入依赖行为方式称为依赖注入简称DI。
在依赖注入中,您仅需声明,不必创建对象,但必须描述如何创建它们。您不是直接在代码中将组件和服务连接在一起,而是描述配置文件中哪些组件需要哪些服务。由 IoC 容器将它们装配在一起。
控制反转:是一种将组件依赖关系的创建和管理置于程序外部的技术。
由容器控制程序之间的关系,而不是由代码直接控制,由于控制权由代码转向了容器,所以称为反转。
对象与对象之间的关系可以简单的理解为对象之间的依赖关系,举例:在类 A 的方法中需要调用类 B 的方法来完成功能,那么首先在 A 类需要有类 B 的一个实例,叫做 A 类依赖于B 类。
一个需要特定的依赖的组件一般会涉及一个依赖对象,在 IOC 的概念中叫做目标 (target) 。换句话说, IOC提供了这样的服务,使一个组件能够在它的整个生命周期中访问它的依赖和服务,用这种方法与它的依赖进行交互。总的来说, IOC能够被分解为两种子类型:依赖注入和依赖查找。
那么,可以通过几种方式完成依赖注入?
通常,依赖注入可以通过三种方式完成:
1) 构造函数注入
2) setter 注入
3) 接口注入
在 Spring Framework 中,仅使用构造函数和 setter 注入。
注入方式:区分构造函数注入和、setter 注入
构造函数注入 | setter 注入 |
---|---|
没有部分注入 | 有部分注入 |
不会覆盖 setter 属性 | 会覆盖 setter 属性 |
任意修改都会创建一个新实例 | 任意修改不会创建一个新实例 |
适用于设置很多属性 | 适用于设置少量属性 |
接着,Spring 中有多少种 IOC 容器?
1)BeanFactory - BeanFactory 就像一个包含 bean 集合的工厂类。它会在客户端要求时实例化 bean。
2)ApplicationContext - ApplicationContext 接口扩展了 BeanFactory 接口。它在 BeanFactory 基础上提供了一些额外的功能。
区分 BeanFactory 和 ApplicationContext。
BeanFactory | ApplicationContext |
---|---|
它使用懒加载 | 它使用即时加载 |
它使用语法显式提供资源对象 | 它自己创建和管理资源对象 |
不支持国际化 | 支持国际化 |
不支持基于依赖的注解 | 支持基于依赖的注解 |
再然后,IoC 可以带来哪些好处?
IoC 的一些好处是:
1)减少代码量。
2)它将使应用程序易于测试,因为它不需要单元测试用例中的任何单例或 JNDI 查找机制。
3)它以最小的影响和最少的侵入机制促进松耦合。
4)它支持即时的实例化和延迟加载服务。
最后,给出Spring IoC 的实现机制。
Spring 中的 IoC 的实现原理就是工厂模式加反射机制。
示例:
package com.spring;
/**
* Created by Liuxd on 2018-11-11.
*/
interface Animal {
public abstract void speak();
}
class Cat implements Animal {
public void speak() {
System.out.println("I am a cat");
}
}
class Dog implements Animal {
public void speak() {
System.out.println("I am a dog");
}
}
class BeanFactory {
public static Animal getInstance(String ClassName) {
Animal f = null;
try {
f = (Animal) Class.forName(ClassName).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
public class Client {
public static void main(String[] a) {
Animal animal = BeanFactory.getInstance("com.spring.Cat");
if (null != animal) {
animal.speak();
}
Animal animal2 = BeanFactory.getInstance("com.spring.Dog");
if (null != animal2) {
animal2.speak();
}
}
}
打印结果:
I am a cat
I amd a dog