1.0 前言

这系列文章是大三上学期JavaEE课程内容的一些笔记,主要学习的对象是JavaEE中常用的Spring框架以及Mybatis框架。

我认为,学习好Spring框架对于软件工程专业的学生是比较重要的,包括但不限于以下好处:

  • 体会软件设计原则是如何实践的
  • 感受各种设计模式在现代开发框架中的应用
  • AOP思想、IOC思想等等的实现方式
  • ...

作为软件开发人员,通过学习Spring框架对自身的基本功的磨练是大有裨益的。

1.1 Spring是什么?

Spring是一款用于简化企业级Java应用开发的分层开源框架,它有着强大的扩展、融合能力,善于将各种单层框架完美地糅合在一起,并建立一个完整体系,统一、高效地构造可提供企业级服务的应用系统。

Spring是一个分层非常清晰并且依赖关系、职责定位非常明确的轻量级架构,主要分为8大模块:数据处理模块(Data Access/Integration)、Web模块、AOP(Aspect Oriented Programming)模块、Aspects模块、Instrumentation模块、Messaging模块、Core Container模块和Test模块。Spring依靠这些基本模块,实现了一个令人愉悦的融合了现有解决方案的零侵入的轻量级框架。

简单来说,Spring是一个容器,能够管理各种Java对象以及它们之间的依赖关系,是软件设计中依赖倒转原则的一种体现。

1.数据处理模块(Data Access)

该模块由JDBC、Transactions、ORM、OXM和JMS等模块组成。

  • JDBC模块提供了不需要编写冗长的JDBC代码和解析数据库厂商特有的错误代码的JDBC-抽象层。

  • Transactions模块支持编程和声明式事务管理。

  • ORM模块提供了流行的Object-Relational Mapping(对象-关系映射)API集成层,包含JPA、JDO和Hibernate等ORM框架。Spring对ORM的支持和封装主要体现在三方面:一致的异常处理体系结构,对第三方ORM框架抛出的专有异常进行了包装;一致的DAO抽象的支持,为每个框架都提供了模板类来简化和封装常用操作,例如 JdbcSupport、HibernateTemplate等;Spring的事务管理机制,为所有数据访问都提供了一致的事务管理。

  • OXM模块提供抽象层,用于支持Object/XML mapping(对象/XML映射)的实现,例如JAXB、Castor、XMLBeans、JiBX和XStream等。

  • JMS模块(Java Messaging Service)包含生产和消费信息的功能。

2.Web模块

该模块由Web、WebSocket、Servlet和Portlet等模块组成。

  • Web模块提供了面向Web开发的集成功能。

  • WebSocket模块提供了面向WebSocket开发的集成功能。

  • Servlet 模块(也被称为SpringMVC 模块)包含 Spring 的 Model-View-Controller(模型-视图-控制器,简称MVC)和REST Web Services实现的Web应用程序。Spring MVC框架使DomainModel(领域模型)代码和Web Form(网页)代码实现了完全分离,并且集成了Spring Framework的所有功能。

  • Portlet模块(也被称为Portlet MVC 模块)是基于Web和Servlet模块的MVC实现。Portlet和Servlet的最大区别是对请求的处理分为Action阶段和Render阶段。在处理一次 HTTP请求时,在 Action阶段处理业务逻辑响应并且当前逻辑处理只被执行一次;而在Render阶段随着业务的定制,当前处理逻辑会被执行多次,这样就保证了业务系统在处理同一个业务逻辑时能够进行定制性响应页面模版渲染。

3.AOP模块

该模块是Spring的代理模块,也是Spring的核心模块,它巧妙地利用了JVM动态代理和CGLIB动态代理面向过程编程,来实现业务零侵入、低耦合的效果。为了确保Spring与其他AOP框架的互用性,Sping AOP模块支持基于AOP联盟定义的API,也就是Aspect模块,与Spring IoC模块相辅相成。其中,我们熟知且常用的事务管理就是利用Spring AOP模块实现的。Spring AOP模块及Spring良好的架构设计及扩展性,使Spring可以融合基本上所有的模块及其他框架,成为真正的集大成者。

4.Aspects模块

该模块提供了与 AspectJ(一个功能强大并且成熟的面向切面编程的框架)的集成,它扩展了Java语言,定义了 AOP语法(俗称织入点语法),持有一个专门的编译器来生成遵守Java字节编码规范的Class文件,使用字节码生成技术来实现代理。Spring自带AOP模块,并且集成了AspectJ框架,使原AspectJ使用者可以快速掌握Spring框架,这同样体现了Spring高融合的特性。

5.Instrumentation模块

该模块是 Spring 对其他容器的集成及对类加载器的扩展实现,其子模块 spring-instrument-tomcat实现了Tomcat Instrumentation代理功能。

6.Messaging模块

该模块是从Spring集成项目(例如 Message、MessageChannel、MessageHandler及其他基于消息应用的基础模块)中抽象出来的,类似于基于注解的Spring MVC编程模块,包含一系列消息与方法的映射注解。

7.Core Container模块

该模块(也叫Spring核心容器模块)是Spring的根基,由Beans、Core、Context、SpEL四个子模块组成,这四个子模块如下所述。

  • Beans模块和Core模块提供框架的基础部分,包含IoC(Inversion of Control,控制反转)和 DI(Dependency Injection,依赖注入)功能,使用 BeanFactory 基本概念来实现容器对Bean的管理,是所有Spring应用的核心。Spring本身的运行都是由这种Bean的核心模型进行加载和执行的,是Spring其他模块的核心支撑,是运行的根本保证。

  • Context(包含 Spring-Context和 Spring-Context-Support两个子模块)模块建立在Core模块和 Beans模块的坚实基础之上,并且集成了 Beans模块的特征,增加了对国际化的支持,也支持Java EE特征。ApplicationContext接口是Context模块的焦点。Spring-Context-Support模块支持集成第三方常用库到Spring应用上下文中,例如缓存(EhCache、Guava)、调度Scheduling框架(CommonJ、Quartz)及模板引擎(FreeMarker、Velocity)。

  • SpEL模块(Spring-Expression Language)提供了强大的表达式语言来查询和操作运行时的对象。

8.Test模块

该模块支持通过组合JUnit或TestNG来进行单元测试和集成测试,并且提供了Mock Object(模仿对象)方式进行测试。在该模块中定义了注释,例如@ContextConfiguration、@WebAppConfiguration@ContextHierarchy@ActiveProfiles,可以被用作元注释来创建自定义注解并避免整个测试套件的重复构造。

总的来说,Spring具有以下特点:

  • 创建Spring的目的就是用来替代更加重量级的的企业级Java技术
  • 简化Java的开发
    • 基于POJO轻量级和最小侵入式开发
    • 通过依赖注入和面向接口实现松耦合
    • 基于切面和惯例进行声明式编程
    • 通过切面和模板减少样板式代码

1.2 侵入式

侵入式:对于EJB、Struts2等一些传统的框架,通常是要实现特定的接口,继承特定的类才能增强功能改变了java类的结构

非侵入式:对于Hibernate、Spring等框架,对现有的类结构没有影响,就能够增强JavaBean的功能

1.3 松耦合

前面我们在写程序的时候,都是面向接口编程,通过DaoFactroy等方法来实现松耦合,代码如下:

private CategoryDao categoryDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.CategoryDAOImpl", CategoryDao.class);

private BookDao bookDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.BookDaoImpl", BookDao.class);

private UserDao userDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.UserDaoImpl", UserDao.class);

private OrderDao orderDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.OrderDaoImpl", OrderDao.class);

DAO层和Service层通过DaoFactory来实现松耦合,如果Serivce层直接new DaoBook(),那么DAO和Service就紧耦合了【Service层依赖紧紧依赖于Dao】。

而Spring给我们更加合适的方法来实现松耦合,并且更加灵活、功能更加强大。(IOC控制反转