概念
预备知识
1. POJO
POJO是Plain Old Java Object的缩写,是软件开发大师Martin Fowler提出的一个概念,指的是一个普通Java类。也就说,你随便编写一个Java类,就可以称之为POJO。之所以要提出这样一个专门的术语,是为了与基于重量级开发框架的代码相区分,比如EJB,我们编写的类一般都要求符合特定编码规范,实现特定接口、继承特定基类,而POJO则可以说是百无禁忌,灵活方便。
2. Javabean 和 Spring 的 bean
-
JavaBeans是一种Java规范定义的一种组件模型,它包含了一些类编码的约定。简单来说,一个类如果拥有一个默认构造函数,拥有公共的访问内部属性且符合命名规范的setter和getter方法,同时实现了io.Serializable接口,就是一个JavaBean(具体的几条规则请百度)。那么为什么要这些约定呢? 因为大家都遵守这些约定,在编写或者修改一个类的时候,就能很容易在可视化的开发环境中进行操作,也更方便地分发给他人。
-
Spring Bean是被Spring维护和管理的POJO。最早Spring只能管理符合JavaBeans规范的对象,这也是为什么称之为Spring Bean的原因。但是现在只要是POJO就能被Spring容器管理起来,而且这也是最为常见的情况
框架的含义
框架,即为解决一个开放性问题而设计的具有一定约束性的支撑结构。它是依据特定的设计,对一类底层 API、流程进行封装而得到的模块。
它帮你做了各种繁琐的事、肮脏的事、或者复杂的事,解决了一些底层 API 的问题,实现了一些更好的新功能,最后给上层提供一个简洁、一致、方便的 API。使用这些 API,程序员可以很方便的完成一些原本可能会很复杂繁琐肮脏的事。
Spring Overview
广义上的Spring(Spring全家桶)包含了 Spring 提供的一整套应用解决方案,包括 Spring、SpringMVC(RESTfull)、Spring JPA(Hibernate Implementation)、Spring Boot、Spring Security 等等。。
不过这里只说 这套体系的核心:Spring Core Technologies,它包括上图的 Core Container
和 AOP
,提供了控制反转 ( Inversion of Control, IoC)和**面向切面编程 (Aspect-Oriented Programming, AOP) **两个核心功能。
控制反转 ( Inversion of Control, IoC) 容器
概念
控制反转,即把控制权交给你使用的 IoC框架。运行时,是先从主类 启动 Ioc框架,再由该框架来创建你的其他类、管理你的类之间的交互。(也可以先创建其他类,但是需要控制反转功能的类一定要由 Spring 创建才行)
这样做可以降低你的代码的耦合度,提高代码内聚度。类之间的协作关系不再需要硬编码在该类中,直接写在 Ioc框架的配置里就好了。
耦合度降低了,变更代码也就变得容易了,也更容易做模拟测试了,项目的可维护性和健壮性自然就提升了。
实现
Spring 通过 依赖注入(Dependency Injection, DI) 实现了控制反转。它使用配置文件(xml/Annotation/JavaConfig)来设置依赖关系,然后在 Spirng 构建这些对象的过程中,自动注入所需的依赖。
container 的角色可以形象地用下图表示:
org.springframework.beans
和 org.springframework.context
这俩包是 Spring IoC 的基础。
org.springframework.beans.factory.BeanFactory
接口定义了最简单的容器,提供基本的 DI 支持。(太底层,一般不用)而 org.springframework.context.ApplicationContext
接口基于 BeanFactory 接口构建,提供更上层的功能。
ApplicationContext
实现类
ApplicationContext 接口只提供应用上下文相关信息,与具体的配置方法是分离的。不同的配置方式对应不同的实现类。这是一种很灵活的方式。
Spirng 自带了多种类型的应用上下文工厂类,不同的工厂类对应不同的配置方法。最有用的几个如下:
- AnnotationConfigApplicationContext:从基于注解的Java配置类中加载应用上下文,可接受参数为 Class 或 String.
- ClassPathXmlApplicationContext:从类路径(包含Jar文件)下的xml配置文件中加载应用上下文
- AnnotationConfigWebApplicationContext:因为 Spring 被主要被用于构建 Web 应用,因此也提供了这两个工厂类。
- XmlWebApplicationContext:同上
应用上下文(ApplicationContext)
从工厂类构建出应用上下文后,就能够使用在 BeanFactory/ApplicationContext 中定义的方法了,常用的几个如下:
- getBean():继承自 BeanFactory 接口,通过 Class/Id 获取对应的 Bean.
- getResources():继承自 ResourcesLoader,用于获取资源.
虽然如此说,但是一般来说你都不需要用到 Spring 提供的方法,这能保证你的代码不会依赖任何 Spring 的 API。
不过有的时候,比如需要在 JavaFx 中使用 Spring 的时候,因为 JavaFx 在读取 fxml 布局文件时(FXMLLoader),会自动注入 Controller,我们就需要用FxmlLoader 实例的setControllerFactory(context::getBean)
,告诉该布局,你的 Controller 需要找 Spring 要,而不应该自己创建。
配置方法
先前说了 Spring 有多种配置方式,不同的方式对应的不同的 ApplicationContext 实现类。
其中主流的两种方式分别是:xml方式 和 Java配置类方式。
因为Java配置类方式能在编译期发现很多潜在问题,因此正在成为主流选择。
xml 越来越被嫌弃(在数据传输领域它也正在被json替代),不过有些事只有 xml 能干,因此也需要学习。
具体的配置方法笔记记在了下一章,因为这一章主要还是概念的梳理。
**面向切面编程 (Aspect-Oriented Programming, AOP) **
使用 AOP 可以实现 关注点分离,每一个切面只需要干一类事(日志、事务管理、安全等),降低代码复杂性。
DI 帮助实现了类之间的解耦,而 AOP 则有助于实现横切关注点(即日志等与业务逻辑无关的事)与具体业务逻辑之间的解耦。
待续
P.S. Spring 曾经的 overview 提供了非常详尽的体系介绍。但是在
2017-7-28 日的一次提交中,整个 overview 都被重写了一遍,然后信息就变得相当简略。因此 overview 暂时只能看旧版文档了。