springboot
springboot
springboot可以帮助我们简单、快速地创建一个独立的、生产级别的spring应用- 尚硅谷教程
1. 创建项目
1.1 maven配置
- 通过
maven创建项目要求继承自springboot-starter-parent,并引入打包插件spring-boot-maven-plugin开发什么场景,导入对应的场景启动器。导入启动器会导入对应的场景的核心依赖,官方的启动器命名为
spring-boot-starter-xxx,第三方的启动器命名为xxx-spring-boot-starter- 导入starter,就会导入autoconfigure包
- autoconfigure 包里面 有一个文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,里面指定了所有启动要加载的自动配置类
- @EnableAutoConfiguration 会自动的把上面文件里面写的所有自动配置类都按需导入进来
- 每个AutoConfiguration给容器中导入一堆组件,组件都是从 Properties中提取属性值
- 每个Property又是和配置文件进行了绑定,因此导入starter、修改配置文件,就能修改底层行为
parent还有一个父项目spring-boot-dependencies,里面定义了所有常见的jar的依赖版本,不需要再提供版本号,当然也可以自定义版本号,根据maven的就近原则提供版本号- 修改
dependency中给定的版本号变量,比如mysql.version,需要在properties中定义 - 直接在
dependency中提供版本号 - 没有经过
dependency管理的jar,需要提供版本号

项目依赖管理 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.5.5</version> </parent> <properties> <java.version>17</java.version> </properties> <dependencies> <!-- web 场景启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- mybatis 场景启动器 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.5</version> </dependency> <!-- 测试场景启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter-test</artifactId> <version>3.0.5</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <!-- 打包插件 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>自动导入原理
场景启动器在导入相关依赖外,还会导入
spring-boot-starter,这是所有启动器的启动器spring-boot-starter导入了spring-boot-autoconfigure包,包含各种场景的自动配置类- 这些自动配置类不全是默认开启的,导入对应的启动器会开启哪个配置
- 修改
1.2 boot配置文件
配置文件中的所有配置项是和某个类的对象值进行绑定的,绑定了配置文件中的值的类称为配置属性类
默认包扫描规则
只会扫描自动使用
@SpringBootApplication注解的主程序类所在的包及子包(即默认扫描当前包)@SpringBootApplication是一个复合注解,相对于同时设置@SpringBootConfiguration:声明当前类为核心配置类,相当于@Configuration@ComponentScan:需要扫描的包路径,寻找需要注册的组件@EnableAutoConfiguration:开启自动配置功能,引入了对应功能会自动配置相关组件
如果希望自定义扫描路径可以使用以下方法指定
@SpringBootApplication(scanBasePackages = "com.example"):扫描指定包及子包下的所有组件@ConfigurationPropertiesScan:默认扫描当前包及子包下的所有配置文件@ConfigurationProperties类(这个类可以将配置文件的内容绑定到对象中)
@SpringBootApplication @ConfigurationPropertiesScan public class RecipeBackendApplication { public static void main(String[] args) { SpringApplication.run(RecipeBackendApplication.class, args); } }
常用配置项可以在官方文档中查看
1.3 常用注解
1.3.1 组件注册
注册配置类
Configuration或SpringBootConfiguration在配置类中通过方法注解
Bean返回需要注册的对象使用组件扫描
ComponentScan,扫描使用Component、Service、Repository、Controller注解的类在配置类上使用
@import(class)注解直接提交某些类进行管理,相对于直接给容器中放入一个组件类,组件的名字默认是全类名@Configuration @Import(UserService.class) public class AppConfig { // @import 相当于下面这种写法 @Bean public UserService userService() { return new UserService(); } }其他注解:来自
spring本身的注解也是默认支持的@Controller:控制器@Service:服务@Repository:数据访问层@Component:一般组件
1.3.2 条件注册
- 如果需要在存在某些类时注册部分组件,可以使用
@Conditional系列注解,可用在配置类或其中的@Bean方法上,还可用在通过@Component等注册的组件类上@ConditionalOnClass:当提供的类列表都存在时注册value:传入一个class对象或列表,如果不存在这些类会在编译时报错ClassNotFoundException- 可以使用
name参数传入完整名称字符串列表
@ConditionalOnMissingClass:当提供的类都不存在时注册value:只能使用名称字符串列表
@ConditionalOnBean:当某个组件存在时注册value:按类型查找,传入一个class对象name:按名称查找,传入一个名称字符串annotation:提供组件上必须存在的注解class对象,如果无指定注解则不算查找到search:查找范围,可以是SearchStrategy.ALL(默认,当前或父容器)或SearchStrategy.CURRENT(仅当前容器)
@ConditionalOnMissingBean:当某个组件不存在时注册value:按类型查找name:按名称查找ignored:忽略的class对象,比如某些子类
@ConditionalOnExpression:当某个表达式为true时注册value:一个SPEL表达式
@ConditionalOnProperty:当某个配置属性在配置文件中存在并满足条件时注册prefix:属性的前缀name:对应的属性路径名称,可以是列表havingValue:如果带有这个属性,要求期望属性值完全相同(字符串比较)才算满足条件matchIfMissing:属性值不存在时,是否满足条件
@ConditionalOnResource:当某个资源文件存在时注册resources:资源文件名称路径
@Configuration // classpath 中必须存在 JdbcTemplate 这个类 @ConditionalOnClass(name = "org.springframework.jdbc.core.JdbcTemplate") // classpath 中必须不存在 DruidDataSource(避免冲突) @ConditionalOnMissingClass("com.alibaba.druid.pool.DruidDataSource") // 必须存在配置:spring.feature.enabled=true @ConditionalOnProperty( prefix = "spring.feature", name = "enabled", havingValue = "true", matchIfMissing = false ) // classpath 中必须存在指定资源文件 @ConditionalOnResource(resources = "classpath:test.properties") // 表达式必须为 true @ConditionalOnExpression( "${spring.feature.enabled:true} && '${spring.profiles.active:dev}' == 'dev'" ) public class ConditionalAutoConfiguration { /** * 当容器中已经存在 DataSource Bean 时,才创建这个 Bean */ @Bean @ConditionalOnBean(DataSource.class) public JdbcTemplate jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } /** * 当容器中不存在 FeatureService Bean 时,才创建 */ @Bean @ConditionalOnMissingBean public FeatureService featureService() { return new FeatureService(); } }
1.3.3 属性绑定
- 不建议对字段直接注入
- 一般字段是
private的,无赋值方法,不方便测试中传入需要测试的对象Mock - 使用注入不会设置为
final,可能被反射修改 - 一般直接使用构造函数注入,配合
Lombok的@RequiredArgsConstructor注解自动生成构造函数
- 一般字段是
