一 Spring IoC容器概述
Spring 容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件。这些对象被称为 Spring Beans,我们将在下一章中进行讨论。
通过阅读配置元数据提供的指令,容器知道对哪些对象进行实例化,配置和组装。配置元数据可以通过 XML,Java 注释或 Java 代码来表示。下图是 Spring 如何工作的高级视图。 Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序。
IOC 容器 具有依赖注入功能的容器,它可以创建对象,IOC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。在Spring中BeanFactory是IOC容器的实际代表者。
Spring 提供了以下两种不同类型的容器。
序号 | 容器 & 描述 |
---|---|
1 | Spring BeanFactory 容器 :它是最简单的容器,给 DI 提供了基本的支持,它用org.springframework.beans.factory.BeanFactory 接口来定义。 |
2 | Spring ApplicationContext 容器:该容器添加了更多的企业特定的功能,例如从一个属性文件中解析文本信息的能力,发布应用程序事件给感兴趣的事件监听器的能力。该容器是由 org.springframework.context.ApplicationContext 接口定义。 |
ApplicationContext 容器包括 BeanFactory 容器的所有功能,所以通常不建议使用BeanFactory。BeanFactory 仍然可以用于轻量级的应用程序,如移动设备或基于 applet 的应用程序,其中它的数据量和速度是显著。
二 Spring BeanFactory容器
Spring 的 BeanFactory 容器
这是一个最简单的容器,它主要的功能是为依赖注入 (DI) 提供支持,这个容器接口在 org.springframework.beans.factory.BeanFactory中被定义。
在 Spring 中,有大量对 BeanFactory 接口的实现。其中,最常被使用的是 XmlBeanFactory 类。这个容器从一个 XML 文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用。
例子:
下面是BeanFactory.java的内容:
package com.zhang.work;
public class BeanFactory {
private String message;
public void getMessage() {
System.out.println(message);
}
public void setMessage(String message) {
this.message = message;
}
}
下面是MainApp.java的内容
package com.zhang.work;
import javax.naming.Context;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
public class MainApp {
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("Beans.xml"));
BeanFactory obj = (BeanFactory) factory.getBean("beanFactory");
obj.getMessage();
}
}
在主程序中,我们要注意两点:
- 第一步利用框架提供的XmlBeanFactory() API去生成工厂bean以及ClassPathResource() API去加载在路径CLASSPATH下可用的bean配置文件。XmlBeanFactory() API负责创建并初始化所有的对象
- 第二步利用第一步生成的 bean 工厂对象的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象,该对象最后可以用于实际的对象。一旦得到这个对象,你就可以利用这个对象来调用任何方法
下面是配置文件Beans.xml 文件中的内容
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="beanFactory" class="com.zhang.work.BeanFactory">
<property name="message" value="This is BeanFactory"/>
</bean>
<!-- more bean definitions go here -->
</beans>
三 Spring ApplicationContext 容器
Spring ApplicationContext 容器
Application Context 是 BeanFactory 的子接口,也被称为 Spring 上下文。
这个容器在 org.springframework.context.ApplicationContext 接口中定义。
最常被使用的 ApplicationContext 接口实现:
- FileSystemXmlApplicationContext: ApplicationContext实现,从classpath获取配置文件;
- ClassPathXmlApplicationContext: ApplicationContext实现,从文件系统获取配置文件。
- WebXmlApplicationContext: 该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。
例子:
下面是BeanFactory.java的内容:
package com.zhang.work;
public class BeanFactory {
private String message;
public void getMessage() {
System.out.println(message);
}
public void setMessage(String message) {
this.message = message;
}
}
下面是MainApp.java的内容
package com.zhang.work;
import javax.naming.Context;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
public class MainApp {
public static void main(String[] args) {
/*
* FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径。
*/
ApplicationContext factory = new FileSystemXmlApplicationContext("D:/Eclipse/ssm/src/Beans.xml");
/*
* ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。
* 在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,
* 因为,容器会从 CLASSPATH 中搜索 bean 配置文件。
*/
ApplicationContext factory = new ClassPathXmlApplicationContext("Beans.xml");
BeanFactory obj = (BeanFactory) factory.getBean("beanFactory");
obj.getMessage();
}
}
在主程序中,我们要注意两点:
- 第一步生成工厂对象。加载完指定路径下 bean 配置文件后,利用框架提供的 FileSystemXmlApplicationContext() / ClassPathXmlApplicationContext() API 去生成工厂 bean。FileSystemXmlApplicationContext() /ClassPathXmlApplication() 负责生成和初始化所有的对象,比如,所有在 XML bean 配置文件中的 bean。
- 第二步利用第一步生成的 bean 工厂对象的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象,该对象最后可以用于实际的对象。一旦得到这个对象,你就可以利用这个对象来调用任何方法
下面是配置文件Beans.xml 文件中的内容
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="beanFactory" class="com.zhang.work.BeanFactory">
<property name="message" value="This is BeanFactory"/>
</bean>
<!-- more bean definitions go here -->
</beans>
四 详解IoC容器
在Spring Ioc容器的代表就是org.springframework.beans包中的BeanFactory接口
BeanFactory接口提供了IoC容器最基本功能,而org.springframework.context包下的ApplicationContext接口扩展了BeanFactory,还提供了与Spring AOP集成、国际化处理、事件传播及提供不同层次的context实现 (如针对web应用的WebApplicationContext)。
简单说, BeanFactory提供了IoC容器最基本功能,而 ApplicationContext 则增加了更多支持企业级功能支持ApplicationContext完全继承BeanFactory,因而BeanFactory所具有的语义也适用于ApplicationContext。
容器实现一览:
- XmlBeanFactory: BeanFactory实现,提供基本的IoC容器功能,可以从classpath或文件系统等获取资源
(1) File file = new File("fileSystemConfig.xml"); Resource resource = new FileSystemResource(file); BeanFactory factory = new XmlBeanFactory(resource);
(2) Resource resource = new ClassPathResource("fileSystemConfig.xml"); BeanFactory factory = new XmlBeanFactory(resource);
- ClassPathXmlApplicationContext: ApplicationContext实现,从classpath获取配置文件;
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath.xml");
- FileSystemXmlApplicationContext: ApplicationContext实现,从文件系统获取配置文件。
BeanFactory beanFactory = new FileSystemXmlApplicationContent("classpath.xml");
ApplicationContext接口获取Bean方法简介:
Modifier and Type | Method and Description |
---|---|
Object | getBean(String name) 根据名称返回一个Bean,客户端需要自己进行类型转换 |
< T > T | getBean(String name, Class< T > requiredType) 根据名称和指定的类型返回一个Bean,客户端无需自己进行类型转换,如果类型转换失败,容器抛出异常; |
< T > T | getBean(Class< T > requiredType) 根据指定的类型返回一个Bean,客户端无需自己进行类型转换,如果没有或有多于一个Bean存在容器将抛出异常; |
IoC容器如何工作?
- 准备配置文件: :就像前边Beans.xml配置文件一样,在配置文件中声明Bean定义也就是为Bean配置元数据。
- 由IoC容器进行解析元数据: IoC容器的Bean Reader读取并解析配置文件,根据定义生成BeanDefinition配置元数据对象,IoC容器根据BeanDefinition进行实例化、配置及组装Bean。
- 实例化IoC容器: 由客户端实例化容器,获取需要的Bean。
执行过程如图2-5