本文首发于稀土掘金。该平台的作者 逐光而行 也是本人。
前身——Spring
对EJB规范(Enterprise Java Beans)的颠覆
EJB规范的缺点:程序员需要耗费大量时间精力实现该规范所要求的各种类,还要管理其生命周期,违背了“将精力放在业务功能本身上”的初衷。
为了解决这个问题,就有了Spring系列。
Spring核心概念
IoC(inversion of control)和DI(dependency injection)
从本质上看,IoC和DI描述的是同一个事情,都是使得被依赖着不再由依赖者直接创建,而是由专门的 容器 来管理,从而实现解耦。
AOP(aspect(切面) oriented programming)
什么是切面
切面是一组模块化的且可以被多个类复用的逻辑。
什么时候用切面?
当目标对象的一段程序在某个执行点的切入点被判定为真时,切面逻辑会被触发执行,并将切面和目标对象连接在一起,这个过程被称为weaving(织入)
作用
将业务逻辑和非业务逻辑分离
Q:SpringAOP和AspectJ的异同及联系?
同:AspectJ由Eclipse基金会发布,也是AOP思想的实现。
异:两者实现的原理以及最终目标不同。
- SpringAOP可根据runtime的不同状态在java的动态代理技术或CGLIB代理技术之间切换;而AspectJ是在编译期和类装载期织入。
- Spring系只是简单实现了Spring框架需要的AOP功能,而AspectJ是一个大而全的Java实现。
联系:Spring框架也支持AspectJ。
SpringBoot设计理念
Convention Over Configuration(约定大于配置)
大部分项目的配置都是相似的,所以可以将最佳实践(指业界专家大佬的经验)和默认配置进行自动化装配,如管理Spring应用中的各类Bean。
SpringBoot核心1——SpringBoot Starter
- 用途:作为“开始”,它可以很方便地帮助人们创建项目,能用Maven Archetype做的事情,用Spring Initializer(就是官网上的那个项目创建页)一样能做,而且更方便,不需要程序员考虑集成软件时的版本兼容问题。
- 实现:所有依赖被预先定义到pom.xml中,引用starter后,所需依赖就能自动添加到项目中。
starter的使用如图所示:
SpringBoot核心2——Auto Configuration
体现:以在pom.xml中增加一项配置为例
(昨晚我初次创建SpringBoot项目时,发现无法引用@RestController,经上网搜索解决方案,在pom.xml的依赖配置中新增了以下一项,再启动就成功了)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
这个过程发生了什么
除了pom中的配置外,我并没有增加别的代码或配置,这说明SpringBoot自动完成了相应Bean的装配工作,减少了我设置配置文件的工作量。过程如下:
- 应用启动时,扫描项目classpath中存在的框架类。
- 检查显式配置。
- 结合Condition自动完成相应Bean的装配。而Condition和@Conditional注解相联系,从而控制某个Bean是否被加载。
如何实现自动配置?
通过对源码分析可知:SpringBoot利用Condition对各种常用的开源框架定义了AutoConfiguration类,并将其放在spring-boot-autoconfigure-2.*.jar/META-INF/spring.factories中。项目启动时,会按照相应的condition判断是否需要注册相应的类到Spring Context。
(源码分析路径:EnableAutoConfiguration类,AutoConfigurationImportSelector类,spring-boot-autoconfigure-2.*.jar/META-INF/spring.factories)
SpringBoot核心3——Properties
- 加载配置项:@ConfigurationProperties
- 加载除默认的application.properties外的其他配置文件:@PropertySource
- 默认配置的寻址路径是从里到外(从当前目录一直寻到根目录),其中最先开始找的优先级最高。虽然最后会采用最开始找到的那个,但并不是因为找到了就停止寻找,只是因为后面找到的优先级低,而高优先级会覆盖低优先级。
- YML优先级高于application.properties
- 可通过spring.config.name和spring.config.location改变SpringBoot配置的默认行为。
application.properties注入顺序
(越靠前优先级越高)
- Devtools
- @TestPropertySource
- @SpringBootTest
- 命令行指定参数。优先级:Java>spring
- Servlet相关。优先级:Config>Context
- JNDI
- Java系统参数
- 操作系统环境变量
- RandomValuePropertySource随机数
- jar包外的配置文件
- @Configuration 上的@PropertySource参数
- SpringApplication.setDefaultProperties
profile(spring框架本身就有)
- 作用:将环境隔离开来。如开发环境和生产环境
- 使用方法:可以添加多个不同的配置文件,并在启动应用时通过启动参数指定profile加载不同的文件。
spring.profiles.active=xx(yy)
SpringBoot核心4——Actuator
使用场景
项目已经部署上线,发现有问题,无法直接调试。
基础方案:JMX(Java Management Extension)
在SpringBoot中的封装方案:通过Actuator暴露和访问JMX的MBean。
配置方式
- 在pom.xml中添加actuator相关的内容
效果
运行之后可以发现,控制台输出多了这一项:
点开Endpoint,可以看到如下内容:
可以通过在浏览器输入对应网址/点击选项中的内容选择用浏览器打开,查看结果。
如查看health时,该结果表示容器状况良好,运行正常。
两点注意事项:
- 控制某个endpoint开放还是关闭:
在application.properties中添加如下代码:management.endpoint.{endpointName}.enabled:true/false
- 发现某个endpoint通过web直接访问时404 not found,如metrics:
management.endpoints.web.exposure.include=metrics
设置成功后网页如图所示
SpringBoot核心5——Embedded Container
SpringBoot无需配置容器,因为它内置了容器。
也可以通过一些操作将内置的容器换掉或者使SpringBoot部署在独立容器中。(不过我还暂时没有这方面的需求,就先放一放了,等用到再去了解操作,现在要知道理论上是可行的)
参考文献
- SpringBoot官网
- 《微服务从小白到专家》 姚秋晨 张昕 卿睿著