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 {@NullableString getId();String getApplicationName();String getDisplayName();long getStartupDate();@NullableApplicationContext 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配置文件后,利用框架提供的FileSystemXmlApplicationContextAPI 去生成工厂bean。FileSystemXmlApplicationContext负责生成和初始化所有的对象,比如,所有在XML ``bean配置文件中的bean。第二步利用第一步生成的上下文中的
getBean()方法得到所需要的bean。 这个方法通过配置文件中的beanID 来返回一个真正的对象。一旦得到这个对象,就可以利用这个对象来调用任何方法。
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缓存池中,以供外层的应用程序进行调用。
