前言
Spring Framework 作为一个优秀的开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。
现在的Spring已然发展成了一个平台,引用Spring官网的原话:
From configuration to security, web apps to big data – whatever the infrastructure needs of your application may be, there is a Spring Project to help you build it. Start small and use just what you need – Spring is modular by design.
Main Projects:
- Spring Framework
- Spring Boot
- Spring Cloud
- Spring Security
- Spring Data
- ...
这里只列出了最近比较火的 Spring Project,更多Project 请参考:https://spring.io/projects
本篇着重介绍 Spring Framework整体架构,希望能改对 Spring Framework框架有一个初步的全面的认识,并且学习其架构设计方面的一些理念和方法。
Spring Framework源码地址:https://github.com/spring-projects/spring-framework
Spring Framework的整体架构
Spring Framework总共有十几个组件,其中核心组件只有三个:Core、Context 和 Beans。
Spring Framework 3.x 的总体架构图
spring3-modules.png组成 Spring Framework的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
- Spring Core(核心容器):核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
- Spring Context(上下文):Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如:JNDI、EJB、电子邮件、国际化、校验和调度功能。
- Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
- Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
- Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
- Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
- Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
从图中可以看出,IOC 的实现包 spring-beans 和 AOP 的实现包 spring-aop 也是整个框架的基础,而 spring-core 是整个框架的核心,基础的功能都在这里。
在此基础之上,spring-context 提供上下文环境,为各个模块提供粘合作用。
在 spring-context 基础之上提供了 spring-tx 和 spring-orm包,而web部分的功能,都是要依赖spring-web来实现的。
Spring Framework 4.x 的系统架构图
spring4-modules.pngSpring Framework 4.x对比Spring Framework 3.2.x的系统架构变化:
从图中可以看出,总体的层次结构没有太大变化,变化的是 Spring 4.0.3去掉了 struts 模块(spring-struts包)。现在的 Spring mvc的确已经足够优秀了,大量的 web 应用均已经使用了 Spring mvc。而 struts1.x 的架构太落后了,struts2.x 是 struts 自身提供了和 Spring 的集成包,但是由于之前版本的 struts2 存在很多致命的安全漏洞,所以,大大影响了其使用度,好在最新的2.3.16版本的 struts 安全有所改善,希望不会再出什么大乱子。
web 部分去掉了 struts 模块,但是增加 WebSocket 模块(spring-websocket包),增加了对 WebSocket、SockJS 以及 STOMP 的支持,它与 JSR-356 Java WebSocket API 兼容。另外,还提供了基于 SockJS(对 WebSocket 的模拟)的回调方案,以适应不支持 WebSocket 协议的浏览器。
同时,增加了 messaging 模块(spring-messaging),提供了对 STOMP 的支持,以及用于路由和处理来自 WebSocket 客户端的 STOMP 消息的注解编程模型。spring-messaging 模块中还 包含了 Spring Integration 项目中的核心抽象类,如 Message、MessageChannel、MessageHandler。
如果去看源代码的话,还可以发现还有一个新增的包,加强了 beans 模块,就是 spring-beans-groovy。应用可以部分或完全使用 Groovy 编写。借助于 Spring 4.0,能够使用 Groovy DSL 定义外部的 Bean 配置,这类似于 XML Bean 声明,但是语法更为简洁。使用Groovy还能够在启动代码中直接嵌入Bean的声明。
还有一些:
- 删除过时的包和方法。具体API变动可以参考变动报告,第三方类库至少使用2010/2011年发布的版本,尤其是Hibernate 3.6+, EhCache 2.1+, Quartz 1.8+, Groovy 1.8+, and Joda-Time 2.0+。Hibernate Validator要求使用4.3+,Jackson 2.0+。
- Java 8支持。当然也支持Java6和Java7,但最好在使用Spring框架3.X或4.X时,将JDK升级到Java7,因为有些版本至少需要Java7。
- Java EE 6和7。使用Spring4.x时Java EE版本至少要6或以上,且需要JPA 2.0和Servlet 3.0 的支持,所以服务器,web容器需要做相应的升级。一个更具前瞻性的注意是,Spring4.0支持J2EE 7的适用级规范,比如JMS 2.0, JTA 1.2, JPA 2.1, Bean Validation 1.1和JSR-236并发工具包,在选择这些jar包时需要注意版本。
- 使用Groovy DSL定义外部Bean。
- 核心容器提升。
- 支持Bean的泛型注入,比如:@Autowired Repository<Customer> customerRepository
- 使用元注解开发暴露指定内部属性的自定义注解。
- 通过 @Ordered注解或Ordered 接口对注入集合或数组的 Bean 进行排序。
- @Lazy 注解可以用在注入点或 @Bean 定义上。
- 为开发者引入 @Description 注解。
- 引入 @Conditional 注解进行有条件的 Bea n过滤。
- 基于 CGLIB 的代理类不需要提供默认构造器,因为 Spring 框架将 CGLIB 整合到内部了。
- 框架支持时区管理,比如 LocalContext。
- Web提升。
- 增加新的 @RestController 注解,这样就不需要在每个 @RequestMapping 方法中添加 @ResponseBody 注解。
- 添加 AsyncRestTemplate,在开发 REST 客户端时允许非阻塞异步支持。
- 为 Spring MVC 应用程序开发提供全面的时区支持。
- WebSocket,SockJS 和 STOMP 消息。
- 测试提升。
- spring-test 模块里的几乎所有注解都能被用做元注解去创建自定义注解,来减少跨测试集时的重复配置。
- 活跃的 bean 定义配置文件可以编程方式解析。
- spring-core 模块里引入一个新的 SocketUtils 类,用于扫描本地可使用的 TCP 和 UDP 服务端口。一般用于测试需要 socket 的情况,比如测试开启内存 SMTP 服务,FTP 服务,Servlet 容器等。
- 由于 Spring4.0 的原因,org.springframework.mock.web 包现在基于 Servlet 3.0 API。
关于Spring 4.x 新增特性可以参考 What’s New in Spring Framework 4.x
Spring 的设计理念
Spring 是面向 Bean 的编程(BOP, Bean Oriented Programming),Bean 在 Spring 中才是真正的主角。Bean 在 Spring 中作用就像 Object 对 OOP 的意义一样,没有对象的概念就像没有面向对象编程,Spring 中没有 Bean 也就没有 Spring 存在的意义。Spring 提供了 IOC 容器通过配置文件或者注解的方式来管理对象之间的依赖关系。
控制反转模式(也称作依赖性介入)的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器 (在 Spring 框架中是 IOC 容器) 负责将这些联系在一起。
在典型的 IOC 场景中,容器创建了所有对象,并设置必要的属性将它们连接在一起,决定什么时间调用方法。
面向切面编程
面向切面编程,即 AOP(Aspect Oriented Programming),是一种编程技术,它允许程序员对横切关注点或横切典型的职责分界线的行为(例如日志和事务管理)进行模块化。AOP 的核心构造是方面,它将那些影响多个类的行为封装到可重用的模块中。
AOP 和 IOC 是补充性的技术,它们都运用模块化方式解决企业应用程序开发中的复杂问题。在典型的面向对象开发方式中,可能要将日志记录语句放在所有方法和 Java 类中才能实现日志功能。在 AOP 方式中,可以反过来将日志服务模块化,并以声明的方式将它们应用到需要日志的组件上。当然,优势就是 Java 类不需要知道日志服务的存在,也不需要考虑相关的代码。所以,用 Spring AOP 编写的应用程序代码是松散耦合的。
AOP 的功能完全集成到了 Spring 事务管理、日志和其他各种特性的上下文中。
IOC 容器
Spring 设计的核心是 org.springframework.beans 包,它的设计目标是与 JavaBean 组件一起使用。这个包通常不是由用户直接使用,而是由服务器将其用作其他多数功能的底层中介。下一个最高级抽象是 BeanFactory 接口,它是工厂设计模式的实现,允许通过名称创建和检索对象。BeanFactory 也可以管理对象之间的关系。
BeanFactory 支持两个对象模型:
- 单例 模型提供了具有特定名称的对象的共享实例,可以在查询时对其进行检索。Singleton 是默认的也是最常用的对象模型。对于无状态服务对象很理想。
- 原型 模型确保每次检索都会创建单独的对象。在每个用户都需要自己的对象时,原型模型最适合。
bean 工厂的概念是 Spring 作为 IOC 容器的基础。IOC 将处理事情的责任从应用程序代码转移到框架。
结束!
网友评论