Spring 容器介绍
Spring IoC 容器
Spring IoC 容器是 Spring 框架的核心组件之一。IoC(Inverse of Control,控制反转)的含义是:
- 将对象的创建交给 Spring 容器,而不是由程序自己直接 new 实例。这样可以实现解耦。
- Spring 容器会在程序启动时,根据对象的配置元信息(XML或注解),生成相应的对象实例并注入到需要使用的地方。
Spring IoC 容器具体提供以下功能:
- 管理 beans 生命周期:加载配置、实例化、装配属性、执行初始化方法等。
- 通过依赖注入(DI, Dependency Injection),将 beans 的依赖给提供。
- 通过依赖查找,根据 id 或 name 从容器查找 bean 的实例。
- 支持多种配置元信息,使用 XML 配置、注解配置或 Java API 配置。
- 支持自动装配 beans 之间的依赖关系。
- 管理多个不同的 beans 实例。
- 包括很多应用里常见的 beans,如 Hibernate、JDBC 等。
总的说,Spring IoC 容器就是一个 bean 实例仓库,用来管理程序所有的对象生命周期,以及对象间的依赖。
目的是:
- 解耦:对象的创建、配置与依赖获取通过配置方式实现,不需要在代码中 new 实例。
- 依赖注入:Spring 容器会自动将 beans 的依赖注入进来,不需要手动 new 和赋值。
- 大大增强可测试性。
- 整合各种框架方便。
Spring BeanFactory 容器
-
BeanFactory是SpringIOC容器的基本接口,定义了IOC容器的基础功能规范。
-
BeanFactory主要提供了两大功能:
(1)Bean实例化 - 通过配置元信息实例化、配置Bean
(2)依赖注入 - 将Bean的依赖关系注入到Bean中 -
Spring中有多种BeanFactory接口实现:
(1)最常用的是XmlBeanFactory,它从XML配置文件中读取元信息,用于实例化、配置Bean
(2)其他实现还有GroovyBeanFactory、ClassPathXmlApplicationContext等 -
使用场景:
(1)适用于资源有限的应用场景,如移动端、Applet等
(2)也可用于希望更底层控制IOC容器的场景 -
BeanFactory的优点:
(1)精简,不需要过多功能
(2)资源占用少,适合客户端应用
(3)可自定义程度高 -
BeanFactory的缺点:
(1)需要自行编码读取配置、获取Bean实例
(2)不支持企业级功能,扩展性差
(3)与Spring高级容器整合困难 -
更高级的容器ApplicationContext建立在BeanFactory基础之上,提供了事务、AOP等企业级功能,是更常用的首选。
-
BeanFactory相关接口如BeanFactoryAware等主要是为了兼容旧版本代码和整合第三方框架。
-
一般情况下,使用ApplicationContext为主,只有在资源受限或者需要底层控制时,才会考虑使用BeanFactory。
综上,BeanFactory主要设计为一个轻量级的IOC容器,提供了Spring IOC的基础功能,但实际应用中,更多地使用的是功能更全面的ApplicationContext。
下面是文件 HelloWorld.java 的内容:
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
下面是文件 MainApp.java 的内容:
package com.tutorialspoint;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class MainApp {
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory
(new ClassPathResource("Beans.xml"));
HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");
obj.getMessage();
}
}
在主程序当中,我们需要注意以下两点:
- 第一步利用框架提供的 XmlBeanFactory() API 去生成工厂 bean 以及利用 ClassPathResource() API 去加载在路径 CLASSPATH 下可用的 bean 配置文件。XmlBeanFactory() API 负责创建并初始化所有的对象,即在配置文件中提到的 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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
<property name="message" value="Hello World!"/>
</bean>
</beans>
如果你已经完成上面的内容,接下来,让我们运行这个应用程序。如果程序没有错误,你将从控制台看到以下信息:
Your Message : Hello World!
Spring ApplicationContext 容器
Spring ApplicationContext 容器是 Spring IoC 容器的一种具体实现,是 Spring 框架中最重要的容器之一。与 BeanFactory 容器相比,ApplicationContext 容器提供了更多的功能和特性。
ApplicationContext 容器在启动时会读取配置文件或者注解,自动创建和管理 Bean 实例,并在需要的时候将它们注入到其他 Bean 中。同时,ApplicationContext 容器还提供了以下功能:
-
国际化支持:可以方便地实现多语言支持。
-
事件传播:可以方便地实现事件驱动的编程模型。
-
AOP 支持:可以方便地实现面向切面编程。
-
Web 应用支持:可以方便地实现 Spring MVC、RESTful Web Services 等 Web 应用。
-
安全性支持:可以方便地实现基于 Spring Security 的安全控制。
-
JMS 支持:可以方便地实现基于 JMS 的消息传递。
在使用 ApplicationContext 容器时,可以选择不同的实现方式,如 XML 配置、注解配置、Java 配置等。无论使用哪种方式,都可以通过 ApplicationContext 容器来管理应用程序中的对象,从而实现了应用程序的灵活性和可扩展性。
需要注意的是,ApplicationContext 容器是一个重量级的容器,因为它在启动时会自动创建和装配所有 Bean 实例。如果应用程序中的 Bean 数量较多,或者配置文件较大,启动时间可能会较长。因此,在一些特定场景下,可以使用 BeanFactory 容器来代替 ApplicationContext 容器,以提高应用程序的启动速度。
下面是一个使用 Spring ApplicationContext 容器实现的 HelloWorld 示例代码:
首先,需要在 pom.xml 文件中添加 Spring 相关依赖:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.9</version>
</dependency>
</dependencies>
然后,在 resources 目录下,创建一个名为 applicationContext.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 id="helloWorld" class="com.example.HelloWorld">
<property name="message" value="Hello, World!"/>
</bean>
</beans>
在上面的配置文件中,定义了一个名为 helloWorld
的 Bean,它的类型是 com.example.HelloWorld
,并且设置了一个名为 message
的属性,值为 "Hello, World!"。
接下来,编写 HelloWorld 类:
package com.example;
public class HelloWorld {
private String message;
public void setMessage(String message) {
this.message = message;
}
public void printMessage() {
System.out.println(message);
}
}
在上面的代码中,定义了一个名为 message
的属性和一个名为 printMessage()
的方法,用于打印消息。
最后,在主方法中,使用 ApplicationContext 容器来获取 HelloWorld 实例,并调用其 printMessage()
方法:
package com.example;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.printMessage();
}
}
在上面的代码中,使用 ClassPathXmlApplicationContext
类创建一个 ApplicationContext 容器,并指定配置文件的路径为 applicationContext.xml
。然后,通过 getBean()
方法获取名为 helloWorld
的 Bean 实例,并将其强制转换为 HelloWorld 类型。最后,调用 printMessage()
方法打印消息 "Hello, World!"。
运行上述代码,输出的结果为:Hello, World!
。