spring

Spring是Java编写的快速开发框架。集成大量三方包
Spring Framework Documentation :: Spring Framework
Spring Boot Reference Documentation

Spring示例:
https://github.com/xkcoding/spring-boot-demo.git
https://github.com/eugenp/tutorials.git

Quick Start

  1. 引入依赖,Maven 声明
  2. 声明主配置类 标识为 @SpringBootApplication,调用SpringApplication#run(java.lang.Class<?>, java.lang.String...)静态方法创建实例,加载Spring功能
  3. 写 restful 接口;加外部化配置(可选,这是写业务逻辑的地方)
  4. 运行主配置类

Core

组件支持

Bean管理IOC

面向对象以对象为单位组织程序。创建对象这个操作不是业务功能,侵入业务,Spring 使用 Map 管理(创建、依赖管理、生命周期) 单例 Bean
涉及理念:

Java中对象创建的方式

Spring 可以管理的 Bean类型

涉及的模块

Bean 依赖 声明
@Resource
private 类B Bean名;

类循环依赖解决:属性注入可解决,引入中间存储 Map,利用类创建的时间差

Bean生命周期

启动时的 Bean 扩展接口: 接口回调

1. 解析 Bean源  
面向资源 {@link BeanDefinitionReader} / {@link BeanDefinitionParser} xml  
2. 注册Bean {@link BeanDefinitionRegistry}  
3. 类加载  
{@link ClassLoader} / Java Security 安全控制 / ConfigurableBeanFactory  
4. 实例化Bean Instantiation   构造器注入依赖  
5. Aware接口回调阶段:开放 Spring中的资源  
 BeanNameAware  
 BeanClassLoaderAware  
 BeanFactoryAware Bean工厂创建Bean  
 EnvironmentAware  
 EmbeddedValueResolverAware  
 ResourceLoaderAware 获取资源加载器读取资源文件  
 ApplicationEventPublisherAware Bean可发布事件  
 MessageSourceAware  
 ApplicationContextAware 提供Bean  
6. 初始化Bean Initialization BeanPostProcessor
 Bean Map<属性,值> {@link PropertyValues}  
{@link javax.annotation.PostConstruct} / {@link InitializingBean#afterPropertiesSet()} / {@link Bean#initMethod()}  
7. 延迟初始化Bean Lazy Initialization  
{@link Lazy}  
8. 销毁Bean Destroy  
{@link javax.annotation.PreDestroy} / {@link DisposableBean#destroy()} / {@link Bean#destroyMethod()}  
9. Bean 垃圾回收(GC)  
{@link AbstractApplicationContext#close()}  
{@link org.springframework.context.ApplicationContext}  
{@link CommandLineRunner} ???

ApplicationContext,功能

// Bean 存储 DefaultListableBeanFactory https://www.jianshu.com/p/ecd1cdd20e1b
// 缓存完全实例化的Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

存在问题

外部化配置

  1. 配置文件,application.yml ;compile / run 传递环境变量/命令行参数
  2. 配置类
    1. @Import( MyConfiguration.class ) / @Enable* 引入配置类,@Configuration 标注配置类 MyConfiguration,@ComponentScan/ 其作为Bean定义加载到Spring上下文

读取配置文件
org.springframework.core.io.support.SpringFactoriesLoader#loadSpringFactories

MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result = new LinkedMultiValueMap();
while(urls.hasMoreElements()) {
    URL url = (URL)urls.nextElement();
    UrlResource resource = new UrlResource(url);
    Properties properties = PropertiesLoaderUtils.loadProperties(resource); //通过Properties加载资源
    Iterator var6 = properties.entrySet().iterator();
    while(var6.hasNext()) {
        Entry<?, ?> entry = (Entry)var6.next();
        String factoryTypeName = ((String)entry.getKey()).trim();
        String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
        int var10 = var9.length;
        for(int var11 = 0; var11 < var10; ++var11) {
            String factoryImplementationName = var9[var11];
            result.add(factoryTypeName, factoryImplementationName.trim());
        }
    }
}
cache.put(classLoader, result);

方法扩展AOP

AOP,面向切面编程
解决OOP (Object Oriented Programming)静态化语言、侵入性扩展的局限,通过反射和代理模式实现
设计模式:代理模式、拦截器模式
原理

// 目标方法,期待被扩展的方法
public void bizMethod(){}

// AOP对 目标方法 进行扩展,使用动态代理:ClassLoader类加载时生成代理类字节码,运行时method.invoke()反射调用目标方法
// 字节码不一定要有文件,也可能是生成在内存中的字节数组
// 1. implements+ composition,要求必须有 interface;  新建类,与 目标方法 implements same interface 
// ref: JDK 动态代理 Proxy.newProxyInstance(ClassLoader,Interface,InvocationHandler) 
public void proxyMethod(){
	log.info("请求目标方法前");
	commonInterface.bizMethod();
	log.info("请求目标方法后");
}
// 2. Inheritance
// Cglib 动态代理:Enhancer字节码增强器,创建代理类;MethodInterceptor 拦截目标方法
public void proxyMethod(){
	log.info("请求目标方法前");
	super.bizMethod();
	log.info("请求目标方法后");
}

模块

延伸
类扩展 编程范式

通知Events

事件监听机制
ApplicationListener是Spring框架中的一个接口,用于监听应用程序中的事件并执行相应的逻辑。以下是几个ApplicationListener的主要实现类和它们所实现的功能:

  1. ContextRefreshedEvent:当应用程序上下文被成功刷新(即完成初始化)时触发。在此事件中可以执行与应用程序初始化相关的后续逻辑。
  2. ContextStartedEvent:当应用程序上下文启动时触发。可以在此事件中执行与应用程序启动相关的额外逻辑。
  3. ContextStoppedEvent:当应用程序上下文停止时触发。可以在此事件中执行与应用程序停止相关的清理或处理逻辑。
  4. ContextClosedEvent:当应用程序上下文关闭时触发。可以在此事件中执行与应用程序关闭相关的资源释放或清理逻辑。
  5. ApplicationStartedEvent:当Spring应用程序开始启动时触发,早于上下文的创建。可以在此事件中执行与应用程序启动相关的逻辑。
  6. ApplicationEnvironmentPreparedEvent:在应用程序环境准备就绪之后、上下文创建之前触发。可以在此事件中执行与环境配置相关的逻辑。
  7. ApplicationFailedEvent:当应用程序启动失败时触发。可以在此事件中执行与应用程序错误处理相关的逻辑。

这些ApplicationListener的实现类可以通过注册到Spring应用程序上下文中,监听相应的事件并在事件发生时执行自定义的逻辑。通过实现不同的ApplicationListener接口并重写相应方法,开发人员可以针对不同的事件来处理特定的业务逻辑,扩展和定制应用程序的行为。

请注意,除了上述提及的几个常见实现外,还有其他ApplicationListener的子类和扩展,可以根据需求进行进一步的研究和使用。

// org.springframework.context.event.SimpleApplicationEventMulticaster#multicastEvent(org.springframework.context.ApplicationEvent, org.springframework.core.ResolvableType)
// org.springframework.context.event.AbstractApplicationEventMulticaster
Map<ListenerCacheKey, ListenerRetriever> retrieverCache = new ConcurrentHashMap(64);

private class ListenerRetriever {  
    public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet();
 }

## 表达式SpEL

框架/Tools/Readme#Java元素

String 类型的 SpEL,可以声明在注解上,做运行时计算,输出一个结果
字符串 -> 语法分析 -> 生成表达式对象 -> (添加执行上下文) -> 执行此表达式对象 -> 返回结果

【小家Spring】SpEL你感兴趣的实现原理浅析spring-expression~(SpelExpressionParser、EvaluationContext、rootObject)(上)-阿里云开发者社区 (aliyun.com)

类型

Validation, Data Binding, Type Conversion、JSON

辅助支持

依赖配置starters

默认依赖配置

日志

Web容器

内嵌Web容器,完全控制应用生命周期

loader

通过Maven 将应用打成Jar,可通过 java -jar 启动

资源环境配置

Resources, Environment
yml doc springboot
features.external-config
yml 占位符

spring:  
  web:  
    resources:  
      # 外部化配置优先于内部  
      static-locations: file:/static/,classpath:/static/

devtools

开发功能,自动重启,jar包会禁用此功能

actuator

Spring Boot Actuator Web API Documentation
执行器端点(HealthEndpoint、EnvironmentEndpoint、BeansEndpoint) 允许监控应用
WebMvcEndpointManagementContextConfiguration 加载
http://192.168.0.139:9326/actuator/health

Test

spring-boot-starter
	spring-boot
		spring-context:
		spring-core:Cglib代理;
	spring-boot-autoconfigure
	spring-boot-starter-logging


+- org.springframework.boot:spring-boot-starter-web:jar:2.7.5:compile
|  +- org.springframework.boot:spring-boot-starter:jar:2.7.5:compile
|  |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.7.5:compile
|  |  \- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile
|  +- org.springframework.boot:spring-boot-starter-json:jar:2.7.5:compile
|  |  \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.13.4:compile
|  +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.7.5:compile
|  +- org.springframework:spring-web:jar:5.3.23:compile
|  \- org.springframework:spring-webmvc:jar:5.3.23:compile

spring-core:提供用于异常处理和版本检测的基本类,以及不特定于框架任何部分的其他核心助手。
支持注解

  1. 开启功能 @EnableXXX

功能支持

GitHub - spring-projects/spring-boot: Spring Boot

Data Access

spring-jdbc
spring-orm
spring-tx

spring-boot-starter-data-jdbc
druid-spring-boot-starter
Mybatis
DAO 支持(DAO Support)
O/R映射(O/R Mapping)
mybatis-plus-boot-starter
redisson-spring-boot-starter

事务抽象(Transactions)

mybatis
配置:分页
动态SQL
缓存
mybatis-plus
通用CRUD
条件构造器
代码生成
插件扩展
自定义全局操作
Redis
RedisTemplate
Redisson
数据类型,常用操作,主从搭建,哨兵集群,日志持久化
应用:数据共享,单点登录,计数器,限流,点赞,排行榜,分布式锁
雪崩,击穿,穿透,更新一致性

ref: database

Web

spring-web

@RestController=@Controller+@ResponseBody

web.servlet
此模块用于 映射(HTTP请求/响应,业务代码),并提供 线程池 和 校验支持

Web on Servlet Stack :: Spring Framework
WebMvcAutoConfiguration (Spring Boot 3.1.0 API) 配置类声明核心功能:

SpringBoot 处理请求流程

接口请求

字典
/dicts?dictType=xxx
/dicts
可以用同一个接口声明返回其值,不使用路径匹配注解(否则会报错:param not present)

@GetMapping("/dicts")  
public List<DictDataVO> dicts(String dictType){  
    return dictDataService.getDictDataParamNullable(dictType);  
}

接口命名规范:Java开发都需要参考的一份命名规范 - 知乎 (zhihu.com)

支持:
线程池:TaskExecution
校验:Validation:LocalValidatorFactoryBean.getValidator().validate

Validation
Java Bean Validation :: Spring Framework
LocalValidatorFactoryBean 可使用国际化 i18n messages.properties Common Application Properties (spring.io)

  1. 单字段校验 ConstraintValidator
  2. 字段关联校验 DefaultGroupSequenceProvider
  3. 字段关联比较

SpringSecurity
用户认证
权限管理
Shiro

Logging
XXL-JOB
drools 规则引擎
Filter, Listener,拦截器
spring-boot-starter-web
Spring MVC
WebSocket
Netty
IO模型,Channel,Buffer,Selector,Netty模型
WebSocket

Servlet

JSON
Jslt GitHub - schibsted/jslt: JSON query and transformation language
jsonSchema JSON Schema | The home of JSON Schema (json-schema.org)

模板引擎
Template Engines,数据与展示逻辑分离

远程调用(Remoting)

Messaging-统一消息服务
Kafka,RocketMQ

本地任务(Tasks)本地调度(Scheduling)-多线程+调度表达式
Control#定时调度
xxl-job-spring-boot-starter
缓存抽象(Caching)
Testing(Junit5)
Mock:对象生成不需要Web容器
Ng
正向代理,反向代理(负载均衡)
命令,配置,动静分离,集群搭建

MQ
RocketMQ, Kafka
生产消费模型,交换机模型,死信队列,延迟队列,消息持久化,Java操作,集群搭建
微服务
Dubbo:服务提供/消费
Spring Cloud:
服务注册发现,Consul
配置中心:Nacos
负载均衡
服务调用 Feign
服务限流,降级,熔断
服务容错
网关 Gateway
分布式服务总线
分布式链路追踪 Sleuth,SkyWalking
分布式
理论:CAP,BASE
一致性算法:Raft, Paxos, 一致性哈希
分布式事务:2PC,3PC,MQ事务消息,最大努力通知,LCN
ID:Leaf
服务调用:RPC
存储:HDFS
监控:Zabbix,Prometheus

Elastic
部署
Jenkins
Docker:容器,镜像,部署,Dockerfile, Compose, Macheine, Swarm, 多阶段构造
K8s:Ingress,资源类型,Pod(声明周期,安全策略),架构(组件,对象),工作负载,Kubectl,集群管理

messaging

Scheduling

Caching

工具包

EasyExcel

读Excel | Easy Excel (alibaba.com)

设计模式

API抽象

模块化设计

功能稳定性
可扩展性
可测试性

编程模型

面向对象-契约接口
BeanDefinition:Bean抽象

面向切面-动态代理/字节码提升
面向元编程:注解,属性配置-占位符/外部化配置
面向模块编程:Maven,@Enable
面向函数编程:lambda,Reactive异步非阻塞

规约

面向对象
契约接口:Aware、BeanPostProcessor ...
设计模式:观察者模式、组合模式、模板模式 ...
对象继承:Abstract* 类

函数驱动
函数接口:ApplicationEventPublisher
Reactive:Spring WebFlux

面向切面
动态代理:JdkDynamicAopProxy
字节码提升:ASM、CGLib、AspectJ...

模块驱动
Maven Artifacts
Java 9 Automatic Modules
Spring @Enable* 模

面向元注解
注解:模式注解(@Component、@Service、@Respository ...)
配置:Environment 抽象、PropertySources、BeanDefinition ...
泛型:GenericTypeResolver、ResolvableType ...

模块设计

spring-framework/docs/5.3.25

spring-boot-2.7.8 feature

spring-context-5.3.25.jar