Spring—Springboot篇
SpringBoot
-
版本要求
- SpringBoot稳定版本2.x,目前主流版本正在转向SpringBoot3.x
- Java稳定版本JDK8,目前主流版本正在转向JDK17
- maven版本要求3.6.7及以上
-
标准
pom.xml结构:如果使用阿里云脚手架建议修改为标准结构
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.2</version><relativePath /> <!-- lookup parent from repository --></parent><groupId>com.wyh</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>demo</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
启动流程
-
大致流程
- 运行启动类:创建
SpringApplication实例 - 加载
ApplicationListener实例:监听应用生命周期的所有事件 - 准备运行环境:读取配置文件、命令行参数、系统属性等
- 创建并配置
ApplicationContext:创建应用上下文 - Bean 初始化:加载IOC,执行依赖注入(DI)
- 启动内嵌服务器:默认Tomcat
- 回调执行:执行
ApplicationRunner/CommandLineRunner,运行容器启动后的个性化需求
- 运行启动类:创建
-
容器就绪回调:
ApplicationRunner在容器最后阶段执行,早于ApplicationReadyEvent,晚于ContextRefreshedEvent**
/**
* 任务简单且无需容器参数解析场景下,推荐使用CommandLineRunner,代码复杂度低
*/
@Component
public class MyCommandLineRunner implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {// 执行初始化任务System.out.println("CommandLineRunner executed with args: " + Arrays.toString(args));}
}
/**
* ApplicationRunner是对CommandLineRunner的原始参数进行进一步封装,提供更灵活的参数解析能力
*/
@Component
public class MyApplicationRunner implements ApplicationRunner { @Overridepublic void run(ApplicationArguments args) throws Exception {// 获取命令行参数System.out.println("ApplicationRunner executed with args: " + args.getSourceArgs());// 获取选项参数(如--name=value)if (args.containsOption("name")) {System.out.println("Option name value: " + args.getOptionValues("name"));}}
}
依赖管理机制
- SpringBoot项目会带有一个父项目
Spring-boot-starter-parent,它对绝大部分场景启动器做了版本管理
<!--父项目进行版本管理-->
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.2</version><relativePath/> <!-- lookup parent from repository -->
</parent>
自动配置机制
场景启动器:场景启动器包含了功能需要的所有依赖
Spring-boot-starter-xxx是Spring官方提供的场景启动器;xxx-Spring-boot-starter是第三方提供的场景启动器- 官方场景启动器会自动管理版本,三方场景启动器需要手动指定版本、
- Spring会在启动时自动注册场景启动器的相关Bean,属性取默认值,可以后续修改
自动配置流程
- 启动 Spring Boot 应用:通过
@SpringBootApplication启动类启动- 扫描自动配置类: 加载所有自动配置类
- 条件化匹配:根据当前项目的依赖和配置,决定哪些自动配置类生效
- 创建 Bean 并绑定属性:为生效的自动配置类创建 Bean,并绑定
application.yml中的配置(如果有)- 注入到 Spring 容器:将配置好的 Bean 注册到 IoC 容器中
-
全局配置文件和配置类
- 如果场景启动器相关Bean如果修改属性过程较复杂,建议使用配置类(例如配置
rabbitMQ) - 非场景启动器相关Bean,SpringBoot不会自动注册,必须使用配置类注册(例如配置
redisson) - 简单场景或者静态属性可以使用配置文件
- 如果场景启动器相关Bean如果修改属性过程较复杂,建议使用配置类(例如配置
@Configuration
public class RedissonConfig {//redisson没有场景启动器,因此需要使用配置类注册Bean@Beanpublic RedissonClient redissonClient(){Config config = new Config();config.setCodec(new StringCodec()).useSingleServer().setAddress("redis://127.0.0.1:6379").setPassword("123456").setDatabase(0);return Redisson.create(config);}
}
@Configuration
public class RabbitMQConfig {//rabbitMQ虽然有场景启动器,但初始化配置过程很复杂,不适合放在全局文件中@Beanpublic ConnectionFactory rabbitConnectionFactory() {CachingConnectionFactory factory = new CachingConnectionFactory();...return factory;}
}
配置类增强功能
-
@ConditionalOnXxx:条件成立时才会通过配置类注册Bean@ConditionalOnClass:如果项目中存在这个类,则触发行为@ConditionalOnMissingClass:如果项目中不存在这个类,则触发指定行为@ConditionalOnBean:如果IOC容器中存在组件,则触发指定行为@ConditionalOnMissingBean:如果IOC容器中不存在组件,则触发指定行为@ConditionalOnProperty:如果配置文件中有对应的值才执行
-
@ConfigurationProperties:由统一配置文件信息注入Bean,较于@Value,避免了繁杂的配置文件,可以集中快速管理- 配置类必须有
getter、setter @ConfigurationProperties(prefix = "xxx")选择配置类中的键,支持多层级匹配- 支持松散匹配(
databaseUrl↔database-url),但建议使用严格匹配 - 非配置类中加载也可以加在属性值,在类上加
@EnableConfigurationProperties即可 @ConfigurationProperties也可以注解于方法上,映射返回值实例
- 配置类必须有
-
@Profile:标记类或方法,指定其在特定 Profile 激活时生效
- 逻辑或表达式:
@Profile({"dev", "test"})、@Profile("dev | test")(Spring 6+ 支持)- 逻辑与表达式:
@Profile("dev & test")- 否定表达式:
@Profile("!prod")- 复杂表达式:
@Profile("dev & !cloud")
#application.yaml
db:druid:url: jdbc:mysql://localhost:3306/learn_project?serverTimezone=GMT%2B8username: rootpassword: 123456
@Configuration
@ConfigurationProperties(prefix = "db.druid")
@Data // 注意!必须有getter、setter
public class DataSourceConfiguration {private String url; // 成员属性值会自动注入private String username;private String password;@Bean@ConditionalOnClass(DruidDataSource.class) //有DruidDataSource时才加载Bean@Profile("!test") // 非test环境下生效public DataSource druidDataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}
}
嵌入式容器
- SpringBoot引入场景启动器后,会自动内置所需的容器,例如Tomcat
<!-- 热部署 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional>
</dependency>
