一、框架概览:从 family 到 module

Spring 起源于 2003 年,它作为 Java EE 平台规范的补充,而不是完全拥抱 specification。

Spring 可以指的是 entire family of projects。也可以单指 Spring Framework(换言之,Spring Framework 本身也只是 family 的一部分)。

Spring Framework 被模块化了,它的核心只包括 core container(主要解决依赖注入问题)。但是针对不同的应用架构,它提供不同的支持,包括 messaging、transactionl、persistence 和 web。这些模块原本命名为 “spring-core” 和 “spring-context”,在 Java 9 的 jigsaw 项目来临之时,也开始支持 module path,生成"自动模块名"清单项,并且定义语言级别的模块名,如"spring.core"、“spring.context”。

Spring 支持的 JSR 有:

  • Servlet API (JSR 340)
  • WebSocket API (JSR 356)
  • Concurrency Utilities (JSR 236)
  • JSON Binding API (JSR 367)
  • Bean Validation (JSR 303)
  • JPA (JSR 338)
  • JMS (JSR 914)
  • TA/JCA setups for transaction coordination
  • Dependency Injection (JSR 330)
  • Common Annotations (JSR 250)

spring-framework-architecture
spring-modules
spring-modules.xmind

二、构建 spring-framework 源码

介绍下使用到的 Gradle 工具

《一篇文章讲清楚Gradle与Gradle Wrapper的区别》

comments:

  • Gradle Wrapper 提供了一种"在本地构建中,使用特定版本的 Gradle 进行构建"的功能。
  • 换言之,对于大多数敏捷迭代的项目而言,应该选择 ./gradlew clean build,而不是 gradle clean build。这样不会遇到 pluginManagement 之类的问题,这样说来,每个项目都是自构建的。
  • 要么 IDE(像 Android Studio)自带 gradle wrapper,要么项目自带一个 gradle/wrapper 文件夹,这个文件夹里指定了 gradle-wrapper.properties。 这个命令专门指定了特定版本的 gradle。-all.jar、-bin.jar、-src.jar 分别代表不同的包。
  • gradlew是在linux,mac下使用的,gradlew.bat是在window下使用的,提供在命令行下执行gradle命令的功能。-这种 w 的中间层策略,值得我们学习。
  • 每个项目本身都带有特定的 plugin(可能在下一版本失效),所以 gradle 专门写了针对 gradle project 的 upgrade 指南​。
  • .gradle文件夹,就是那个跟项目第一个文件夹,带点的那个。那个对我们没什么用,他是gradle运行的时候产生的一些记录性的文件。我们不需要关注。

实际构建的过程

./gradlew -a :spring-webmvc:test

这里面蕴藏一个模式./gradlew -a :项目名:task名

代码风格

Spring 使用 tab 而不是空格(和很多其他项目恰恰相反),替换空格的方法是find . -type f -name "*.java" -exec perl -p -i -e "s/[ \t]$//g" {} \;

Spring 的代码不提倡使用静态引用:

Static imports should not be used in production code. They should be
used in test code, especially for things like import static
org.assertj.core.api.Assertions.assertThat;.

成员的顺序:

  1. static fields
  2. normal fields
  3. constructors
  4. (private) methods called from constructors
  5. static factory methods
  6. JavaBean properties (i.e., getters and setters)
  7. method implementations coming from interfaces
  8. private or protected templates that get called from method
  9. implementations coming from interfaces
  10. other methods
  11. equals, hashCode, and toString

Spring 使用埃及括号。Braces mostly follow the Kernighan and Ritchie style (a.k.a., “Egyptian brackets”) for nonempty blocks and block-like constructs。

三、Spring 与数据库的若干技巧

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#  登录服务器
mysql -u username -pdev -h hostname databaseName

# 如何重命名一个 db
mysqldump emp > emp.out
mysql -e "CREATE DATABASE employees;"
mysql employees < emp.out
mysql -e "DROP DATABASE emp;"

# mysqldump 的用法

mysqldump -u username -h hostname -ppassword databaseName > /exportpath/dump.sql

# 使用 brew 控制 mysql
brew install mysql
brew services restart mysql


# 登录本机 root 用户
mysql -uroot

# 使用密码登录本机 root 用户
mysql -uroot -p
# 标准格式
mysql -u USERNAME -pPASSWORD -h HOSTNAMEORIP --port=6002 DATABASENAME

# 执行 sql,导出结果到 csv 文件
mysql -uabc -pefg -hip地址 -P端口号 --default-character-set=utf8或者utf8mb4 --batch --raw < ~/example.sql > ~/example.csv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- 查看表的字段信息
desc 表名;
-- 查看表的所有信息
show create table 表名;
-- 添加主键约束
alter table 表名 add constraint 主键 (形如:PK_表名) primary key 表名(主键字段);
-- 添加外键约束
alter table 从表 add constraint 外键(形如:FK_从表_主表) foreign key 从表(外键字段) references 主表(主键字段);
-- 删除主键约束
alter table 表名 drop primary key;
-- 删除外键约束
alter table 表名 drop foreign key 外键(区分大小写);
-- 修改 root 密码,注意要分登录态,也可以参考 https://blog.csdn.net/qq_33285112/article/details/78982766
alter user 'root'@'localhost' identified by '123456'

Liquibase

Use Liquibase to Safely Evolve Your Database Schema

数据库的演化,可以是 evolve,也可以是 refactor。

Flyway

Database Migrations with Flyway

这里使用的术语是 remodel。

MariaDB4j

Using MariaDB4j for a Spring Boot Embedded Database

注意它对 datasource 的抽象。

H2 和 JPA 的速成搭配

(待补充)

四、Spring Boot 部署启动

基于 loader 的启动命令

1
java(可以重命名为应用名) -Denv=test -Dspring.profiles.active=test -Dn=appName(可以对 ENV 求值) -Xmx4096m -Xms4096m -XX:MetaspaceSize=128M -XX:+CMSClassUnloadingEnabled -DapplicationMode=spring -Dlogger.file=conf/logback.xml -Dconfig.file=conf/application-test.conf -javaagent:/usr/local/services/appName/libs/opentelemetry-javaagent-1.19.2.jar -XX:+CMSPermGenSweepingEnabled -XX:+PrintGCDetails -Xloggc:./logs/gc-%t.log -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:+UseContainerSupport -XX:HeapDumpPath=./logs/heapdump.data -cp ./conf:./lib/*(这个搜索路径就用 应用程序打出的 jar,里面自然带有 JarLauncher 这个主类) org.springframework.boot.loader.JarLauncher