临河可以做网站的公司,项目建设目标怎么写,vue cdn做的网站,织梦怎么建设论坛网站IoC 是 Inversion of Control 的简写#xff0c;译为“控制反转”#xff0c;它不是一门技术#xff0c;而是一种设计思想#xff0c;是一个重要的面向对象编程法则。 Spring 通过 IoC 容器来管理所有 Java 对象的实例化和初始化#xff0c;控制对象与对象之间的依赖关系。…IoC 是 Inversion of Control 的简写译为“控制反转”它不是一门技术而是一种设计思想是一个重要的面向对象编程法则。 Spring 通过 IoC 容器来管理所有 Java 对象的实例化和初始化控制对象与对象之间的依赖关系。我们将由 IoC 容器管理的 Java 对象称为 Spring Bean它与使用关键字 new 创建的 Java 对象没有任何区别。IoC 容器是 Spring 框架中最重要的核心组件之一它贯穿了 Spring 从诞生到成长的整个过程。
控制反转IoC
在传统的 Java 应用中一个类想要调用另一个类中的属性或方法通常会先在其代码中通过 new Object() 的方式将后者的对象创建出来然后才能实现属性或方法的调用。为了方便理解和描述我们可以将前者称为“调用者”将后者称为“被调用者”。也就是说调用者掌握着被调用者对象创建的控制权。 但在 Spring 应用中Java 对象创建的控制权是掌握在 IoC 容器手里的其大致步骤如下。
开发人员通过 XML 配置文件、注解、Java 配置类等方式对 Java 对象进行定义例如在 XML 配置文件中使用 bean 标签、在 Java 类上使用 Component 注解等。Spring 启动时IOC 容器会自动根据对象定义将这些对象创建并管理起来。这些被 IOC 容器创建并管理的对象被称为 Spring Bean。当我们想要使用某个 Bean 时可以直接从 IOC 容器中获取例如通过 ApplicationContext 的 getBean() 方法而不需要手动通过代码例如 new Obejct() 的方式创建。 IoC 带来的最大改变不是代码层面的而是从思想层面上发生了“主从换位”的改变。原本调用者是主动的一方它想要使用什么资源就会主动出击自己创建但在 Spring 应用中IoC 容器掌握着主动权调用者则变成了被动的一方被动的等待 IoC 容器创建它所需要的对象Bean。 这个过程在职责层面发生了控制权的反转把原本调用者通过代码实现的对象的创建反转给 IoC 容器来帮忙实现因此我们将这个过程称为 Spring 的“控制反转”。
依赖注入DI
在了解了 IoC 之后我们还需要了解另外一个非常重要的概念依赖注入。 依赖注入Denpendency Injection简写为 DI是 Martin Fowler 在 2004 年在对“控制反转”进行解释时提出的。Martin Fowler 认为“控制反转”一词很晦涩无法让人很直接的理解“到底是哪里反转了”因此他建议使用“依赖注入”来代替“控制反转”。 在面向对象中对象和对象之间是存在一种叫做“依赖”的关系。简单来说依赖关系就是在一个对象中需要用到另外一个对象即对象中存在一个属性该属性是另外一个类的对象。
例如有一个名为 B 的 Java 类它的代码如下。
public class B {String bid;A a;
}
从代码可以看出B 中存在一个 A 类型的对象属性 a此时我们就可以说 B 的对象依赖于对象 a。而依赖注入就是基于这种“依赖关系”而产生的。 控制反转核心思想就是由 Spring 负责对象的创建。在对象创建过程中Spring 会自动根据依赖关系将它依赖的对象注入到当前对象中这就是所谓的“依赖注入”。
IoC 的工作原理
在 Java 软件开发过程中系统中的各个对象之间、各个模块之间、软件系统和硬件系统之间或多或少都存在一定的耦合关系。 若一个系统的耦合度过高那么就会造成难以维护的问题但完全没有耦合的代码几乎无法完成任何工作这是由于几乎所有的功能都需要代码之间相互协作、相互依赖才能完成。因此我们在程序设计时所秉承的思想一般都是在不影响系统功能的前提下最大限度的降低耦合度。 IoC 底层通过工厂模式、Java 的反射机制、XML 解析等技术将代码的耦合度降低到最低限度其主要步骤如下。
在配置文件例如 Bean.xml中对各个对象以及它们之间的依赖关系进行配置我们可以把 IOC 容器当做一个工厂这个工厂的产品就是 Spring Bean容器启动时会加载并解析这些配置文件得到对象的基本信息以及它们之间的依赖关系IOC 利用 Java 的反射机制根据类名生成相应的对象即 Spring Bean并根据依赖关系将这个对象注入到依赖它的对象中。
由于对象的基本信息、对象之间的依赖关系都是在配置文件中定义的并没有在代码中紧密耦合因此即使对象发生改变我们也只需要在配置文件中进行修改即可而无须对 Java 代码进行修改这就是 Spring IOC 实现解耦的原理。
IoC 容器的两种实现
IoC 思想基于 IoC 容器实现的IoC 容器底层其实就是一个 Bean 工厂。Spring 框架为我们提供了两种不同类型 IoC 容器它们分别是 BeanFactory 和 ApplicationContext。
BeanFactory
BeanFactory 是 IoC 容器的基本实现也是 Spring 提供的最简单的 IoC 容器它提供了 IoC 容器最基本的功能由 org.springframework.beans.factory.BeanFactory 接口定义。 BeanFactory 采用懒加载lazy-load机制容器在加载配置文件时并不会立刻创建 Java 对象只有程序中获取使用这个对对象时才会创建。
示例 1
BeanFactory 的使用。
在 HelloSpring 项目中将 MainApp 的代码修改为使用 BeanFactory 获取 HelloWorld 的对象具体代码如下。
public static void main(String[] args) {BeanFactory context new ClassPathXmlApplicationContext(Beans.xml);HelloWorld obj context.getBean(helloWorld, HelloWorld.class);obj.getMessage();
} 2运行 MainApp.java控制台输出如下。 message : Hello World! BeanFactory 是 Spring 内部使用接口通常情况下不提供给开发人员使用。
ApplicationContext
ApplicationContext 是 BeanFactory 接口的子接口是对 BeanFactory 的扩展。ApplicationContext 在 BeanFactory 的基础上增加了许多企业级的功能例如 AOP面向切面编程、国际化、事务支持等。 ApplicationContext 接口有两个常用的实现类具体如下表。
实现类描述示例代码ClassPathXmlApplicationContext加载类路径 ClassPath 下指定的 XML 配置文件并完成 ApplicationContext 的实例化工作ApplicationContext applicationContext new ClassPathXmlApplicationContext(String configLocation);FileSystemXmlApplicationContext加载指定的文件系统路径中指定的 XML 配置文件并完成 ApplicationContext 的实例化工作ApplicationContext applicationContext new FileSystemXmlApplicationContext(String configLocation);
参数 configLocation 用于指定 Spring 配置文件的名称和位置如 Beans.xml。
演示 ApplicationContext 的使用
修改 HelloSpring 项目 MainApp 类中 main() 方法的代码具体代码如下。
public static void main(String[] args) {//使用 FileSystemXmlApplicationContext 加载指定路径下的配置文件 Bean.xmlBeanFactory context new FileSystemXmlApplicationContext(D:\\springworkspace\\
HelloSpring\\src\\Beans.xml);HelloWorld obj context.getBean(helloWorld, HelloWorld.class);obj.getMessage();
} 运行 MainApp.java控制台输出如下
message : Hello World!