05-SpringBoot 高级
对应原始资料:
springBoot高级、SpringBoot高级原理-部署.md
一、自动配置原理(核心)
1. @SpringBootApplication
java
@SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan2. @EnableAutoConfiguration
- 用
@Import(AutoConfigurationImportSelector.class)导入一堆自动配置类。 - 加载
META-INF/spring.factories(SpringBoot 2.x)/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(3.x)。 - 每个自动配置类(如
DataSourceAutoConfiguration)带@Conditional条件注解,满足条件才生效。
3. 常用条件注解
| 注解 | 含义 |
|---|---|
@ConditionalOnClass | classpath 有指定类才生效 |
@ConditionalOnMissingBean | 容器中没有指定 Bean 才生效 |
@ConditionalOnBean | 有指定 Bean 才生效 |
@ConditionalOnProperty | 配置项满足条件才生效 |
@ConditionalOnWebApplication | 是 Web 应用才生效 |
4. 一句话原理
SpringBoot 启动时加载所有自动配置类(
xxxAutoConfiguration),每个配置类根据条件决定是否生效;一旦生效就用@Bean向容器注册组件,组件需要的参数从xxxProperties类(绑定 yml)读取。
5. 案例:DataSourceAutoConfiguration
- 引入
mysql-connector、druid。 - 容器中没有 DataSource → 自动配置 HikariCP/Druid。
- 参数从
DataSourceProperties读取,绑定 yml 的spring.datasource.*。 - 你可以自定义一个 DataSource Bean,覆盖默认(
@ConditionalOnMissingBean)。
二、自定义 Starter
1. 为什么自定义 Starter
团队内封装通用组件(如统一认证、限流、监控),做成 starter 让其他项目一行依赖即可用。
2. 步骤
① 创建普通模块,依赖 spring-boot-autoconfigure。
② 写配置类:
java
@ConfigurationProperties(prefix = "hello")
@Data
public class HelloProperties {
private String name;
private String prefix;
}
@Configuration
@EnableConfigurationProperties(HelloProperties.class)
@ConditionalOnProperty(prefix = "hello", name = "enabled", havingValue = "true")
public class HelloAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public HelloService helloService(HelloProperties p) {
return new HelloService(p);
}
}③ 注册自动配置:resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.itheima.hello.HelloAutoConfiguration④ 使用方依赖该 starter,在 yml 配置即可触发。
三、Profile 多环境
yaml
spring:
profiles:
active: dev # 激活 dev文档块方式(单文件):
yaml
spring:
profiles: dev
server:
port: 8080
---
spring:
profiles: prod
server:
port: 80四、配置优先级(高 → 低)
- 命令行参数
--server.port=9090。 - JNDI / 环境变量。
- jar 同目录的
application.yml。 - jar 内的
application-{profile}.yml。 - jar 内的
application.yml。
五、内嵌容器
- 默认 Tomcat。
- 换 Jetty / Undertow:排除 tomcat starter,引入对应 starter。
- 调优:
server.tomcat.threads.max=200等。
六、Actuator 生产监控
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>访问:
/actuator/health:健康检查。/actuator/beans:所有 Bean。/actuator/metrics:指标。- 暴露所有:
management.endpoints.web.exposure.include=*。
七、整合第三方(常用)
1. Redis
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>yaml
spring:
redis:
host: localhost
port: 6379java
@Autowired private StringRedisTemplate redis;
redis.opsForValue().set("k", "v");
String v = redis.opsForValue().get("k");2. Quartz / XXL-Job 定时任务
SpringBoot 原生定时:
java
@EnableScheduling
@SpringBootApplication
public class App { }
@Component
public class Task {
@Scheduled(cron = "0 0 2 * * ?") // 每天凌晨 2 点
public void run() { }
}3. Swagger / Knife4j(接口文档)
xml
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>...</version>
</dependency>访问 /doc.html。
八、部署
1. 打 jar
mvn clean package → java -jar app.jar。
2. 后台运行(Linux)
bash
nohup java -jar app.jar --spring.profiles.active=prod > app.log 2>&1 &3. Docker 部署(见 06 模块)
dockerfile
FROM openjdk:8-jdk
COPY app.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]4. 分层 jar / 增量构建
SpringBoot 默认分层(dependencies / application),配合 Docker 多阶段构建加速。
九、性能与最佳实践
- 关闭 devtools 在生产。
- 用 HikariCP 连接池(默认)。
- 日志用 logback async + 滚动。
- JVM 参数:
-Xms -Xmx -XX:+UseG1GC。 - 用 Lombok / MapStruct 减少模板代码。
练习建议
- 调试启动过程,打印自动配置报告
--debug,看哪些生效哪些不生效。 - 自定义一个 starter(如 hello-spring-boot-starter)。
- 整合 actuator,访问
/actuator/health。 - 用
@Scheduled写一个每天清理日志的任务。 - 用 Docker 部署你的 SpringBoot 项目。