描述
Spring Boot中的Starter是一种非常重要的机制,能够抛弃繁琐的配置,将其统一集成Starter自动装配组件,开发者只需要在maven中添加依赖即可。自动扫描需要加载的实例并启动相应的默认配置,Starter组件摆脱了各种依赖库的处理,需要配置各种信息的困扰。会自动通过classpath路径下的类发现需要的Bean,并注册到IOC容器。使用时,直接通过@Autowired注解调用。
自定义Starter的命名规则
SpringBoot提供的Starter以spring-boot-starter-xxxxx的方式命名
自定义的Start使用xxxxx-spring-boot-starter命名规则,以区分SpringBoot生态提供的Starter
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<scope>provided</scope>
</dependency>
实现方案介绍
-
方案一:加入starter依赖即可直接使用
-
方案二:通过yml配置是否开启使用
-
方案三:热拔插技术,通过注解是否开启
方案一
实体类Bean,可以通过yml或者properties配置修改默认数据
/**
* Properties配置
*
* @author: 苦瓜不苦
* @date: 2022/7/2 17:28
**/
@Data
@ConfigurationProperties("account")
public class AccountProperties {
/**
* 用户名
*/
private String username = "admin";
/**
* 密码
*/
private String password = "admin";
}
配置类,提供方法
/**
* @author: 苦瓜不苦
* @date: 2022/7/2 17:26
**/
@Slf4j
@Configuration
@EnableConfigurationProperties(AccountProperties.class)
public class SendMessageClient {
private final AccountProperties accountProperties;
public SendMessageClient(AccountProperties accountProperties) {
this.accountProperties = accountProperties;
}
public void send(String content) {
log.info("配置yml的数据 >>>>>> {}", JSON.toJSONString(accountProperties));
log.info("方法传入的内容 >>>>>> {}", content);
}
}
注入到IOC容器,在resource文件下创建META-INF/spring.factories。将配置类加载到IOC容器中,无需使用StringBootApplication启动类加载
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.example.SendMessageClient
配置Bean的注释,在resource文件下创建META-INF/spring-configuration-metadata.json。在yml修改配置时,会有注释提示。
{
"properties": [
{
"name": "account.username",
"type": "java.lang.String",
"description": "用户名",
"defaultValue": "admin"
},
{
"name": "account.password",
"type": "java.lang.String",
"description": "密码",
"defaultValue": "admin"
}
]
}
方案二
其实和方案一的配置是一样的,只需要在SendMessageClient类上添加@ConditionalOnProperty(prefix = "account", name = "enable", havingValue = "true")
注解就行
使用是在yml文件中通过account.enable=true
开启,默认是不开启的。如果需要默认开启,则在@ConditionalOnProperty
注解中添加matchIfMissing = true
@ConditionalOnProperty源码说明
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnPropertyCondition.class)
public @interface ConditionalOnProperty {
// 数组,获取对应property名称的值,与name不可同时使用
String[] value() default {};
// 配置属性名称的前缀,比如spring.http.encoding
String prefix() default "";
// 数组,配置属性完整名称或部分名称
// 可与prefix组合使用,组成完整的配置属性名称,与value不可同时使用
String[] name() default {};
// 可与name组合使用,比较获取到的属性值与havingValue给定的值是否相同,相同才加载配置
String havingValue() default "";
// 缺少该配置属性时是否可以加载。如果为true,没有该配置属性时也会正常加载;反之则不会生效
boolean matchIfMissing() default false;
}
方案三
新增一个标记类
/**
* 标记类
*
* @author: 苦瓜不苦
* @date: 2022/7/2 19:09
**/
public class AccountMarker {
}
热拔插注解
/**
* 是否启动注解
*
* @author: 苦瓜不苦
* @date: 2022/7/2 19:01
**/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AccountMarker.class)
public @interface EnableAccount {
}
在SendMessageClient类上添加@ConditionalOnBean(AccountMarker.class)
注解
上诉步骤配置完成之后,即可在项目中使用。只需要在SpringBoot的启动类上添加
@EnableAccount
注解则可以使用。原理解析:通过开启
@EnableAccount
注解,@Import
就会去加载AccountMarker类到IOC容器中,当SendMessageClient类上的@ConditionalOnBean
注解就会判断出AccountMarker类在IOC容器中,然后对SendMessageClient类进行实例化操作,加载到IOC容器中。
扩展知识
注解 | 解析 |
---|---|
@ConditionalOnClass | 应用中包含某个类时,配置才生效 |
@ConditionalOnMissingClass | 应用中不包含某个类时,配置才生效 |
@ConditionalOnBean | Spring的IOC容器中存指定实例对象时,配置才生效 |
@ConditionalOnMissingBean | Spring的IOC容器中不存指定实例对象时,配置才生效 |
@ConditionalOnProperty | 指定参数的值符合要求时,配置才生效 |
@ConditionalOnResource | 指定文件资源存在时,配置才生效 |
@ConditionalOnWebApplication | 处于Web环境时(WebApplicationContext),配置才生效 |
@ConditionalOnNotWebApplication | 非处于Web环境时(WebApplicationContext),配置才生效 |
@ConditionalOnExpression | 指定参数的值符合要求是,配置才生效(和ConditionlOnProperty的区别可以使用springEL表达式) |
@AutoConfigureAfter | 指定Configure类之后加载 |
@AutoConfigureBefore | 指定Configure类之前加载 |
@AutoConfigureOrder | 指定Configure类的加载顺序,默认0 |