本章主要介绍了整体课程设计- 围绕spring的核心功能展开, 主要有五大部分
站在spring整个framework的体系
包含整个课程的核心特性, 还有数据存储, web技术以及技术整合, 比如第三方整合, 如JPA, redis等
spring从1.0到现在的5.x, 每个版本都有一些新特性
在spring2 的时候, 对功能进行了模块化的划分, 让用户实现了按需分配, 按照需要引入模块化的包, 不需要把整个spring都引入进来, 达到一个最小依赖化的原则, 同时减少一些类的冲突.
如java的lamda语法, java5 中的foreach语句等, 这都少不了spring对java不同版本的支持, 如spring3对java5的支持, spring5对java8的支持
我们知道spring是基于java开发的, 肯定离不开对API的实践, 比如xml, 反射, AOP, 动态代理等, 有大量的使用.
另外spring早期自称是一个 javaEE的框架, 因而它对javaEE API也整合的非常透彻, 比如servlet的API, JSP的API, 包括JPA的API, JMS的API.
过去spring有个讲法, spring相当于一个胶水, 他讲所有的API或者是规范整合在一起
同时我们也可以看到spring 有很多自己的实现, 这套体系会实现一套完整的面向对象或者说面向流行的一些编程模型
面向对象的三要素, 继承, 封装, 多态
其中多态是最重要的一个特性, 在java中, 由于只支持单继承, 多实现, 所以接口比较常用.
每个接口都有其语义, 每个语义会决定它的职责. 所以通常我们说, 面向对象编程, 在java里面通常就是面向接口编程.
也就称为, 面向契约接口
这后面也延伸出了一些别的东西, 比如说 GOF 23, 即** 23种设计模式**
面向切面编程在java中的内嵌的一种实现方式就是 动态代理.
这种方式有一定的局限性, 就是动态代理必须基于接口来进行编程.
由于现实情况中不可能所有的代码都是接口, 因此 spring 提供的提升的方式就是, 整合了一些外部的框架, 比如:
ASM, CGLIB, AspectJ, 来帮助我们在类方面做提升. 相当于我们可以在类上面做一些 AOP 的拦截. 比如:
事务, @Transactional, 它可以帮助我们去指定, 是基于接口还是基于类来进行事务控制的.
面向元编程有一个特点, 她不是面向程序的, 而是再程序的基础上面再进行元数据的一些处理.
用于配置的元信息, 通常在用到spring或者其他容器类框架的时候都会有的一个东西, 我们会配置一些类或者属性, 在xml或者properties文件中, 而这些配置可以影响到运行时的一些状态,
比如 spring中可以影响到 依赖注入的方式, 时机等, 或者在 Servlet中影响到一个 Servlet的映射
注解是 java5 里面提升的一个新特性, 这个特性需要JDK支持.
因而spring3 需要java5的支持, 从spring3及以后也大量引入了注解来支持元编程, 比如说 AOP 相关的, @Before, @After等, 或者像Bean的一个定义, 比如 @Bean, @Configuration
主要指两方面:
一个是关于 placeholder, 比如占位符.
在xml或者properties文件中可以通过占位符来动态替换到里面的值, 避免硬编码.
第二个是关于外部化配置,
效果是类似的, 除了替换上面说的, 还可以替换一些代码里面的行为, 比如开关一些阈值, 设置数据库连接信息之类.
另一个是gradle, 都是类似的, 方便模块化的组件
在spring3.0做了一个大量的支持, 但是在后面的版本被认为不是一个趋势, 因而被移除了
java 9 推出了一个自动化模块的特性, spring在实现模块化之后也支持这个特性.
最后一个比较特殊, 前面三个都是面向文件的,是物理特性, 比如maven通过 artifactId, 引入模块化的包等.
@Enable注解则是一种代码的方式, 或者运行时的方式, 在springBoot和cloud用的很多, 比如 @EnableCache
最后这点属于面向对象的补充, 就像面向切面一样, 当然不是太明显
但是spring在lambda方面看不到太多, 这是java的特性.
随着webflux的引入, 异步非阻塞模式会逐渐被熟悉, 这是和传统同步方式所不同的一种模式.
Ioc容器部分要和Bean部分一起看
在spring的官方文档里有一个描述, spring IoC 就是 DI, 但是我们后面会发现这是不对的.
spring Ioc 容器提供了依赖查找和依赖注入两种实现方式, 当然其提供的实现不止这点儿.
大部分来源于Bean实例
大部分来源于Bean实例, 还有一些单体对象或spring的内部对象, 后面会单独说
有了依赖查找和依赖注入, 我们自然会想到他们的来源, 就是第三部分 Bean, 而 spring Ioc 容器 是对Bean进行管理的容器
包括生命周期lifeCycle和Bean的定义
Bean的定义包括一些配置, 也涉及到代码, 这些东西可以进行组装, 注册或者说加入到IoC容器中去, 提供我们依赖查找和依赖注入
有 Bean , 就要有它的作用域(scopes), 或者是我们经常遇到的, 它是不是一个单体对象, 是不是一个原型对象, 以及包括是不是 Request, Appliction, Session 这样的一些作用域, 以及这个作用域具体用到什么地方.
除此之外还有自定义的作用域, 如springCloud中就 定义了一个叫做 Refresh 的作用域, 这个作用域是一个特殊的, 只能用于spring动态Bean的刷新上面的作用域.
这里是spring提供的大量扩展点的一部分, 比如说 Bean的 实例化, 初始化, 销毁等基本的操作
这些并不是spring原创的, 很多容器都有类似的设计, 比如 servlet容器 也有 实例化, 初始化, 销毁等, 但是spring提供了更为丰富的生命周期
元信息需要结合 Bean 和 基础设施两部分来看
spring3之后支持用注解来配置元信息了, 这个不用多说.
元信息的配置, 来源于基础设施中的资源管理, 这包括两种来源, xml文件和properties文件
实际上Bean里面的数据也有它的来源, 来源于元信息, 元信息中的一部分, 就是去配置或者去管理这个数据.
但要注意, 这里的配置数据, 并不是简单的一两个词,
这里的配置, 是指元信息可以配置我们的Bean, 同时也给Bean提供一些数据
这些配置, 可以来源于xml或java代码中. 而数据则来自于一些外部文件占位符, 提供一些阈值来给我们进行使用
基础设施又影响到了元信息和IoC容器, 给元信息提供了一些工具, 同时扩展了IoC容器的功能, 使得IoC容器有了校验, 国际化和事件等的功能
讲到这里我们能够发现, spring的功能都是环环相扣的, 后面内容基本就围绕着这个脉络进行讲解
资源涉及到一些配置文件, 或者流.
那么资源管理就是帮助我们提供一些资源定位的特性, 当流过来的时候, 通过流的内容来进行解析, 生成一些Bean的定义或者一些Bean的元信息, 或者容器元信息来控制我们的容器行为,
也控制我们的Bean的行为, 这就是指的元信息与 Ioc容器 之间关系的第二条线, 控制 , 比如可以控制容器依赖注入的方式, 是否懒加载, 是按照名称的自动绑定, 还是按照类型的自动绑定等等.
为什么在任何配置文件里面,都是一些文本文件, 他们就能转换成对象, 转换成不同数据类型, 这里涉及到的一个核心的逻辑就是类型转换, 后面会有专题进行讨论
这里spring3.0之前和之后有两套对比的实现方案
这个数据绑定还和Bean有关系, 比如 Bean Validation 这个, 进行非空或者超长之类的校验, 校验就是单独的下一个部分
校验涉及两个场景,
第一个是普通的一个业务对象校验
第二个是Web情况的校验
那么校验如果不通过, 就要有个文案, 这个文案和国际化就有关系.
这里用到的是java标准的 Resource Bundle 的一个读取
spring的事件是基于java标准事件来进行实现的, 不过这个事件是设计模式中的观察者模式的扩展.
spring3.0之后支持了泛型, 那么事件也相应支持了泛型事件, 泛型其实也是spring的一个比较核心的特性, 但是我们平常不容易注意到