01
—
前言
Spring是一个开源框架,最早由Rod Johnson创建,并在《Expert One-on-One:J2EE Design and Development》这本著作中进行了介绍。Spring是为了解决企业级应用开发的复杂性而创建的,使用Spring可以让简单的JavaBean实现之前只有EJB才能完成的事情。单Spring不仅仅局限于服务器开发,任何Java应用都能在简单性、可测试性和松耦合等方面从Spring中获益。
Spring官网:https://spring.io/
02
—
2.1 整体架构
Spring框架是一个为Java应用程序的开发提供了综合、广泛的基础性支持的Java平台。Spring帮助开发者解决了开发中基础性的问题,使得开发人员可以专注于应用程序的开发。Spring框架本身亦是按照设计模式精心打造,这使得我们可以在开发环境中安心的集成Spring框架,不必担心Spring是如何在后台进行工作的。
Spring框架至今已集成了20多个模块。这些模块主要被分如下图所示的核心容器(Spring core container)、数据访问/集成(Data Access/Intgeration)、Web与远程调用、AOP(面向切面编程)、工具(Instrumentation)、消息和测试模块(Test)。
2.2 Spring模块
Spring官网可以下载源文件,也可以直接在ide中打开引用的Spring jar包查看Spring模块的结构,里面全是由jar文件组成,Spring4.0中发布版本中包括了20个不同的模块,完整的库JAR文件如图:
2.3 模块详解
2.3.1 Spring核心容器
容器是Spring框架最核心的部分它管理着Spring应用中的bean的创建、配置和管理。在该模块中,包括了Spring bean工厂,它为Spring提供了DI的功能。基于bean工厂,还会发现多种Spring应用上下文的实现,每一种都提供了配置Spring的不同方式。
除了bean工厂和应用上下文,该模块也提供了许多企业服务,如E-mail、JNDI访问、EJB集成和调度。
2.3.2 Spring的AOP模块
这个模块为Spring的面向切面编程提供了丰富的支持,帮助应用对象解耦,借助AOP,将遍布系统的关注点(日志、安全、事务)从它们所应用的对象中解耦出来。
2.3.3 数据访问与集成
使用JDBC编写代码通常会导致大量的样板代码,如获得数据库连接、创建语句、处理结果集到最后关闭数据库连接。Spring 的JDBC和DAO模块抽象了这些样板式代码,使数据库代码变得简单明了,还可因为关闭数据库资源失败而引发的问题。
Spring也提供了ORM(Object-Relational Mapping)模块,建立在对DAO的支持之上,为多个ORM框架提供了一种构建DAO的简便方式。Spring本身不创建,而是集成了许多ORM框架如Hibernate、Java Data Object和iBATIS SQL Maps等。Spring的事务管理支持所有的ORM框架及JDBC。
2.3.4 WEB与远程调用
MVC模式是一种普遍被接受的构建Web应用的方法,它可以帮助用户将界面逻辑与应用逻辑分离。java从来不缺少MVC框架,Apache的Struts、JSF、webWork等都是MVC框架。有助于在web层提升应用的松耦合水平。
除了面向用户的web应用,还提供了了多种构建与其他应用交互的远程调用方案,集成了RMI(Remote Method Invocation)、Hessian等,自带远程调用框架:HTTP invoker,提供了暴露和使用REST API的良好支持。
2.3.5 测试
帮助开着者自测模块和程序,mock对象实现了JNDI、Servlet和Portlet编写的单元测试,加载应用上下文中的bean集合以及Spring上下文中的bean进行交互提供了支持。
03
—
3.1 Spring的核心
Spring可以做很多事情,它为企业级开发者提供了丰富的功能,这些功能的底层依赖于它的两个核心特性,一个是依赖注入(DI dependency injection),另一个是面向切面编程(aspect -oriented programming AOP)。
任何一个有实际意义的应用都会由两个或者更多的类组成,这些类相互之间进行协作来完成特定的业务逻辑。按照传统的做法,每个对象负责管理与自己互相协作的对象(即它所依赖的对象)的引用,这将会导致高度耦合和难以测试的代码。
3.2 依赖注入(DI dependency injection)
DamselRescuingKnight只能执行RescueDamselQuest探险的任务
DamselRescuingKnight在它的构造函数中自行创建了RescueDamselQuest,使得DamselRescuingKnight紧密地和RescueDamselQuest耦合到了一起,极大地限制了对象的业务扩展能力。
通过DI,对象的依赖关系将由系统中负责协调各对象的第三方组件在创建对象的时候进行设定。对象无需自行创建或管理它们的依赖关系,如下图所示:
按照这个依赖关系,对上述他探险任务的代码进行优化,BraveKnight足够灵活可以接受任何扩展:
3.3 应用切面(aspect -oriented programming AOP)
DI能够让互相写作的软件组件保持松散耦合,而面向切面编程(AOP)允许你把遍布应用各处的功能分离出来形成可重用的组件。
面向切面编程往往被定义为促使软件系统实现关注点的分离一项技术。系统由许多不同的组件组成,每一个组件个各负责一块特定功能。除了实现自身核心功能外,这些组件还经常承担着额外的职责。如日志、事务管理和安全这样的系统服务经常融入到自身具有核心业务逻辑的组件中去,这些系统服务通常被成为横切关注点,它们可以跨越系统额多个组件。
可以把切面想象为覆盖在很多组件之上的一个外壳。应用是由那些实现各自业务功能模块组成的。借助AOP,可以使用各种功能层去包裹核心业务层。这些层以声明的方式灵活地应用到系统中,核心应用甚至根本不知道它的存在,可以将安全、事务和日志关注点与核心业务逻辑相分离。
再给上述探险任务代码添加AOP切面应用逻辑:
Minstre1是只有两个方法的简单类,执行探险任务之前,singBeforeQuest方法会被调用;完成探险任务后, singBeforeQuest方法会被调用,两种情况下Minstre1都会通过调用一个PrinsStream类来处理一些事情,这个类是通过构造器注入进来的。
3.4 Spring IOC 控制反转
控制反转是应用于软件工程领域中的,在运行时被装配器对象来绑定耦合对象的一种编程技巧,对象之间耦合关系在编译时通常是未知的。在传统的编程方式中,业务逻辑的流程是由应用程序中的早已被设定好关联关系的对象来决定的。在使用控制反转的情况下,业务逻辑的流程是由对象关系图来决定的,该对象关系图由装配器负责实例化,这种实现方式还可以将对象之间的关联关系的定义抽象化。而绑定的过程是通过“依赖注入”实现的。
控制反转是一种以给予应用程序中目标组件更多控制为目的设计范式,并在我们的实际工作中起到了有效的作用。
依赖注入是在编译阶段尚未知所需的功能是来自哪个的类的情况下,将其他对象所依赖的功能对象实例化的模式。这就需要一种机制用来激活相应的组件以提供特定的功能,所以依赖注入是控制反转的基础。否则如果在组件不受框架控制的情况下,框架又怎么知道要创建哪个组件?
在Java中依然注入有以下三种实现方式:
04
—
总结
Spring框架是一个很大的工厂,上面仅仅介绍了基本的Spring架构和核心的原理及简单应用,还有诸如Spring的BeanFactory工厂、配置及生命周期、而且它里面运用到了很多地设计模式等。全盘吃透Spring的这些内容还是需要花费一点时间,这些内容也值得我们花费时间去掌握。很多分布式微服务架构都是在Spring框架的原理基础上拓展而来的,如SpringBoot的底层就是Spring框架。所以掌握Spring框架原理和内容是重中之重。
更多关于Spring的文章: