先来了解关于 Spring 的几个基本概念:
- 非侵入式
所谓非侵入式,指 Spring 框架的 API 不会在业务逻辑上出现。 - 容器
Spring 提供容器功能,容器可以管理对象的生命周期、对象与对象之间的依赖关系。可以通过写一个配置文件(通常是 XML 文件),在上面定义对象的名字、是否单例模式,以及设置与其他对象的依赖关系。在容器启动后,这些对象就被实例化,可以直接使用,而且依赖关系也建立好了。 - IOC
提供一个控制反转容器。”控制” 就是指对对象的创建、维护、销毁等生命周期的控制,这个过程一般是由我们的程序去主动控制的,如使用 new 关键字去创建一个对象(创建),在使用过程中保持引用(维护),在失去全部引用后由GC去回收对象(销毁)。
“反转” 就是指对对象的创建、维护、销毁等生命周期的控制由程序控制改为由IOC容器控制,需要某个对象时就直接通过名字去IOC容器中获取。 - 依赖注入
依赖注入是处理此类情景的:接管对象的创建工作,并将该对象的引用注入需要该对象的组件。由 Spring 框架为接口的实现,对象的创建进行注入。 - AOP
面向方便编程,将日志、安全、事务管理等服务或功能理解成一个 “方面”,从业务逻辑代码中剥离出来,实现复用。
此外,Spring 还可以实现对 JDBC 的封装和简化,提供事务管理功能,对 Hibernate 的整合,提供 MVC 解决方案,还有对 JNDI、mail 等服务进行了封装。
Bean 工厂的 ApplicationContext
Spring IOC 的核心是 Bean 容器,BeanFactory 采用工厂模式,通过从 XML 配置文件中读取 JavaBean 的定义,实现 JavaBean 的创建、配置和管理。所以 BeanFactory 就是 “IOC容器”。而 ApplicationContext 扩展了 BeanFactory 容器并添加了对 国际化、资源访问、事件传播等方面的支持,成为 JavaEE 应用中首选的 IOC容器,可以在 Java App 和 Java Web 中应用。
ApplicationContext 的中文是”应用上下文”,它继承于 BeanFactory 接口,有三个常用的实现类:
ClassPathXmlApplicationContext
从类路径 ClassPath 中寻找指定的 XML 配置文件完成 ApplicationContext 的实例化工作:1
2ApplicationContext context=new ClassPathXmlApplicationContext(String configLocation);
//configLocation 参数指定 Spring 配置文件的名称和位置FileSystemXmlApplicationContext
从指定的文件系统路径中寻找指定的 XML 配置文件来进行容器的实例化。- XmlWebApplicationContext
从 Web 应用中寻找指定的 XML 配置文件进行容器的实例化。
在 Java 项目中通过 ClassPathXmlApplicationContext 类手工实例化容器,但是在 Web 项目中就不能这样做。Web 项目的启动是由相应的 Web 服务器负责的。因此,在 Web 项目中 ApplicationContext 容器的实例化工作最好交给 Web 服务器来完成,Spring 为此提供了如下两种方式:
基于 ContextLoaderListener 实现
在 web.xml 中添加如下代码:1
2
3
4
5
6
7
8
9<!-- 指定 Spring 配置文件的位置,多个配置文件以逗号分隔 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 指定以 Listener 方式启动 Spring 容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>基于 ContextLoaderServlet 实现
在 web.xml 中添加如下代码:1
2
3
4
5
6
7
8
9
10
11<!-- 指定 Spring 配置文件的位置,多个配置文件以逗号分隔 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 指定以 Servlet 方式启动 Spring 容器 -->
<srevlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Bean 的作用域
容器创建 Bean 后,需要了解 Bean 在容器中是如何在不同作用域下工作的。
Spring 为 Bean 定义了 5 种作用域:
- singleton:在每个 Spring IOC 容器中,一个 Bean 定义对应一个对象实例。
- prototype:一个 Bean 定义对应多个对象实例。
- request:在一次 HTTP 请求中,容器会返回该 Bean 的同一个实例,而对于不同的用户请求,会返回不同的实例。
- session:在一次 HTTP Session 中,容器会返回该 Bean 的同一个实例。而对于不同的 HTTP Session 请求,会返回不同的实例。
- global session:在一个全局的 HTTP Session 中,容器会返回该 Bean 的同一个实例。