IOC 容器
Spring 容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件。这些对象被称为 Spring Beans。
通过阅读配置元数据提供的指令,容器知道对哪些对象进行实例化,配置和组装。配置元数据可以通过 XML,Java 注释或 Java 代码来表示。下图是 Spring 如何工作的高级视图。 Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序。
IOC 容器 是**具有依赖注入功能的容器,它可以创建对象,IOC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。通常new一个实例,控制权由程序员控制,而控制反转()是指new实例工作不由程序员来做而是交给Spring容器来做。在Spring中 BeanFactory
是IOC容器的实际代表者。
Spring 提供了以下两种不同类型的容器:
- BeanFactory:它是最简单的容器,给 DI 提供了基本的支持,它用
org.springframework.beans.factory.BeanFactory
接口来定义。BeanFactory
或者相关的接口,如BeanFactoryAware
,InitializingBean
,DisposableBean
,在 Spring 中仍然存在具有大量的与 Spring 整合的第三方框架的反向兼容性的目的。 ApplicationContext
:该容器添加了更多的企业特定的功能,例如从一个属性文件中解析文本信息的能力,发布应用程序事件给感兴趣的事件监听器的能力。该容器是由org.springframework.context.ApplicationContext
接口定义;
ApplicationContext
容器包括 BeanFactory
容器的所有功能,所以通常建议使用 ApplicationContext
。 BeanFactory
仍然可以用于轻量级的应用程序,如移动设备或基于 applet
的应用程序,其中它的数据量和速度是显著。
Spring BeanFactory 容器
这是一个最简单的容器,它主要的功能是为依赖注入 (DI) 提供支持,这个容器接口在 org.springframework.beans.factory.BeanFactor
中被定义。 BeanFactory
和相关的接口,比如 BeanFactoryAware
、 DisposableBean
、 InitializingBean
,仍旧保留在 Spring 中,主要目的是向后兼容已经存在的和那些 Spring 整合在一起的第三方框架。
在 Spring 中,有大量对 BeanFactory
接口的实现。其中,最常被使用的是**XmlBeanFactory**
类。这个容器从一个 XML 文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用。
在资源宝贵的移动设备或者基于 applet 的应用当中, BeanFactory
会被优先选择。否则,一般使用的是 ApplicationContext
,除非你有更好的理由选择 BeanFactory
。
代码示例
(1)创建HelloWord类
public class HelloWord {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void sayHello(){
System.out.println("hello world!");
}
}
(2)配置文件 bean.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.haan.HelloWord" id="helloWord"></bean> //
</beans>
(3)main函数测试
/**
* @Desc
* @Created By liukuihan
* @date on 2020/5/23
*/
public class Main {
public static void main(String[] args) {
BeanFactory beanFactory =
new XmlBeanFactory(new ClassPathResource("bean.xml"));//<1>
HelloWord helloWord = (HelloWord) beanFactory.getBean("helloWord"); //<2>
helloWord.sayHello(); //<3>
}
}
- <1>:加载bean.xml配置文件,将在
bean.xml
中配置的POJO注入到spring容器中去,即生成Spring bean; - <2>:从spring容器中读取bean id为
hellWord
的bean; - <3>:调用
HelloWord
的sayHello()
方法
在主程序当中,我们需要注意以下两点:
- 第一步利用框架提供的
**XmlBeanFactory()**
API 去生成工厂 bean 以及利用**ClassPathResource()**
API 去加载在路径 CLASSPATH 下可用的 bean 配置文件。**XmlBeanFactory()**
API 负责创建并初始化所有的对象,即在配置文件中提到的 bean。 - 第二步利用第一步生成的 bean 工厂对象的
**getBean()**
方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象,该对象最后可以用于实际的对象。一旦得到这个对象,你就可以利用这个对象来调用任何方法。
(4)执行结果
hello world!
Spring ApplicationContext 容器
ApplicationContext
是 BeanFactory
的子接口,也被成为 Spring 上下文。
我们看下接口ApplicationContext的源码:
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
@Nullable
String getId();
String getApplicationName();
String getDisplayName();
long getStartupDate();
@Nullable
ApplicationContext getParent();
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
我们可以发现ApplicationContext继承了ListableBeanFactory
, HierarchicalBeanFactory
接口,而ListableBeanFactory
和HierarchicalBeanFactory
接口又都继承了BeanFactory 接口。
ApplicationContext
是 spring 中较高级的容器。和 BeanFactory
类似,它可以加载配置文件中定义的 bean,将所有的 bean 集中在一起,当有请求的时候分配 bean。 另外,它增加了企业所需要的功能,比如,从属性文件中解析文本信息和将事件传递给所指定的监听器。这个容器在 org.springframework.context.ApplicationContext interface
接口中定义。
ApplicationContext
包含 BeanFactory
所有的功能,一般情况下,相对于 BeanFactory
,ApplicationContext
会更加优秀。当然,BeanFactory
仍可以在轻量级应用中使用,比如移动设备或者基于 applet
的应用程序。
最常被使用的 ApplicationContext
接口实现:
**FileSystemXmlApplicationContext**
:该容器从XML
文件中加载已被定义的bean
。在这里,你需要提供给构造器XML
文件的完整路径。**ClassPathXmlApplicationContext**
:该容器从XML
文件中加载已被定义的bean
。在这里,你不需要提供XML
文件的完整路径,只需正确配置CLASSPATH
环境变量即可,因为,容器会从CLASSPATH
中搜索bean
配置文件。**WebXmlApplicationContext**
:该容器会在一个web
应用程序的范围内加载在XML
文件中已被定义的bean
。代码示例
修改main函数测试:
public class Main {
public static void main(String[] args) {
// BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("bean.xml")); //<1>
//
// HelloWord helloWord = (HelloWord) beanFactory.getBean("helloWord"); //<2>
// helloWord.sayHello(); //<3>
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
HelloWord helloWord = (HelloWord) context.getBean("helloWord");
helloWord.sayHello();
}
}
在主程序当中,我们需要注意以下两点:
第一步生成工厂对象。加载完指定路径下
bean
配置文件后,利用框架提供的FileSystemXmlApplicationContext
API 去生成工厂bean
。FileSystemXmlApplicationContext
负责生成和初始化所有的对象,比如,所有在XML ``bean
配置文件中的bean
。第二步利用第一步生成的上下文中的
getBean()
方法得到所需要的bean
。 这个方法通过配置文件中的bean
ID 来返回一个真正的对象。一旦得到这个对象,就可以利用这个对象来调用任何方法。
Spring Bean定义
Bean 定义
被称作 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的。bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。这些 bean 是由用容器提供的配置元数据创建的,例如在 XML 的表单中的定义。
bean 定义包含称为配置元数据的信息,下述容器也需要知道配置元数据:
- 如何创建一个 bean
- bean 的生命周期的详细信息
- bean 的依赖关系
上述所有的配置元数据转换成一组构成每个 bean 定义的下列属性。
Bean定义的属性
属性 | 描述 |
---|---|
class | 这个属性是强制性的,并且指定用来创建 bean 的 bean 类。 |
name | 这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数据中,你可以使用 ID 和/或 name 属性来指定 bean 标识符。 |
scope | 这个属性指定由特定的 bean 定义创建的对象的作用域,它将会在 bean 作用域的章节中进行讨论。 |
constructor-arg | 它是用来注入依赖关系的,并会在接下来的章节中进行讨论。 |
properties | 它是用来注入依赖关系的,并会在接下来的章节中进行讨论。 |
autowiring mode | 它是用来注入依赖关系的,并会在接下来的章节中进行讨论。 |
lazy-initialization mode | 延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例。 |
initialization 方法 | 在 bean 的所有必需的属性被容器设置之后,调用回调方法。它将会在 bean 的生命周期章节中进行讨论。 |
destruction 方法 | 当包含该 bean 的容器被销毁时,使用回调方法。它将会在 bean 的生命周期章节中进行讨论。 |
Bean和Spring容器的关系
下图表达了Bean 与 Spring 容器之间的关系:
Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载、实例化Bean,并建立Bean和Bean的依赖关系,最后将这些准备就绪的Bean放到Bean缓存池中,以供外层的应用程序进行调用。