一、什么是SpringBoot starter&为什么要使用starter
SpringBoot中的starter是一种非常重要的机制,能够将完成某项功能的代码&配置统一集成进starter,使用者只需要在springboot项目中引入starter依赖,SpringBoot就能自动扫描到要加载的配置类并启动类加载及装配。
当我们需要在项目中增加某项功能时,我们只需要引入starter的依赖然后使用starter中注册好的bean即可,无需引入完成这项功能的其他类库(这些类库已经在starter中引入了),我们也不需要自己去完成各种配置(starter内部已经配置好了)。SpringBoot提供了针对日常企业应用研发各种场景的spring-boot-starter依赖模块。所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。
二、常见的场景
1.通用模块-短信发送模块
2.基于AOP技术实现日志切面
3.分布式雪花ID,Long-->string,解决精度问题
jackson2/fastjson
4.微服务项目的数据库连接池配置
5.微服务项目的每个模块都要访问redis数据库,每个模块都要配置redisTemplate
也可以通过starter解决
三、自动加载核心注解说明
starter 组件开发,核心是自动注解类的注解顺序,即根据条件进行注解
四、自定义starter的开发流程
① 引包,如下是开发一个starter需要引入最少的maven依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mygroup</groupId>
<artifactId>userstarter-spring-boot-starter</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.14</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
</project>
② 新增autoConfig类
为了控制不同配置类之间的依赖关系(控制自动配置顺序)可以在配置类上使用
AutoConfigureAfter和AutoConfigureBefore注解
@Configuration
@EnableConfigurationProperties({StarterProperties.class})
@ConditionalOnClass(value = {StarterService.class, StarterServiceImpl.class})
//@ConditionalOnBean(name = "applicationRunner")
//@ConditionalOnMissingBean(name = "applicationRunner")
/**
* 条件注解说明
* @ConditionalOnBean 仅在当前上下文中存在某个bean时,才会实例化这个Bean
* @ConditionalOnClass 某个class位于类路径上,才会实例化这个Bean
* @ConditionalOnExpression 当表达式为true的时候,才会实例化这个Bean
* @ConditionalOnMissingBean 仅在当前上下文中不存在某个bean时,才会实例化这个Bean
* @ConditionalOnMissingClass 某个class在类路径上不存在的时候,才会实例化这个Bean
* @ConditionalOnNotWebApplication 不是web应用时才会实例化这个Bean
* @AutoConfigureAfter 在某个bean完成自动配置后实例化这个bean
* @AutoConfigureBefore 在某个bean完成自动配置前实例化这个bean
* @ConditionalOnProperty 通过配置文件中的属性值来控制@Configuration是否生效
*/
public class AutoConfig {
@Resource
private StarterProperties starterProperties;
@Bean
public StarterService starterService(){
return new StarterServiceImpl(starterProperties.getA(), starterProperties.getB());
}
}
StarterServiceImpl、StarterService和StarterProperties定义如下:
public interface StarterService {
void myFun();
}
public class StarterServiceImpl implements StarterService {
private String a;
private String b;
public StarterServiceImpl() {
}
public StarterServiceImpl(String a, String b) {
this.a = a;
this.b = b;
}
@Override
public void myFun() {
System.out.println(a + ":" + b);
}
}
@ConfigurationProperties(prefix = "user.starter")
public class StarterProperties {
private String a;
private String b;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
}
③ 资源目录下新建META-INF/spring.factories文件(也可以在META-INF/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中配置)
spring.factories会被springboot项目自动扫描到并将key:
org.springframework.boot.autoconfigure.EnableAutoConfiguration
对应的类作为Config类进行加载到spring容器中,配置类中定义的bean也会被加载到Spring中。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.test.autoconfig.AutoConfig
④ 执行打包
mvn clean install -DskipTests
⑤ 在springboot项目中使用starter
只需要在pom中引入starter的依赖:
<dependency>
<groupId>com.mygroup</groupId>
<artifactId>userstarter-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
然后直接使用步骤②中定义的bean(starterService)即可。
不同starter注册的spring bean的名称重复了怎么办?
经过实验,如果两个starter内部都定义了名称相同的bean,那么会根据配置的spring.main.allowBeanDefinitionOverriding来决定是否报错,如果该值为false,那么springboot启动会报如下错:
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'smsService', defined in class path resource [com/mygroup/test/autoconfig/SmsAutoConfig.class], could not be registered. A bean with that name has already been defined in class path resource [com/mygroup/autoconfig/MyAutoConfig.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
如果设置为true,那么启动不会报错,但是只会有一个生效另外一个会在beanDefinition加载的时候被覆盖掉