今天的博客主题
SpringBoot ——》SpringBoot自定义starter
starter我们可以理解为一个可拔插式的插件,想用拿来用即可。
比如使用jdbc插件,直接使用spring-boot-starter-jdbc。
使用mongodb,可以使用spring-boot-starter-data-mongodb。
而这些都是springboot帮我们做好的。
当springboot提供的starter不满足我们需要的,我们就需要自己搞一个starter了。
那就自定义一个starter吧
创建maven工程
创建一个maven工程。
需要注意的是自定义 starter 命名规范。
Spring官方Starter通常命名为spring-boot-starter-{name},例如 spring-boot-starter-web。
Spring官方建议非官方Starter命名应遵循{name}-spring-boot-starter的格式
【例】mybatis-plus-spring-boot-starter
POM文件增加依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
spring-boot-autoconfigure 模块通过灵活的 Auto-configuration 注解使 SpringBoot 中的功能实现模块化和可被替换扩展。也是完成自动化配置 Bean 的一个重要依赖。
spring-boot-configuration-processor 从字面意思理解来看是配置处理器,引入这个依赖之后的作用就是你在编写配置文件的时候,会有相应的代码提示。
创建属性配置对象
配置Bean用来接收配置文件所配置的属性配置,比如一些资源地址链接什么的
以 elasticsearch 为例。公司也有用到,对es做些扩展支持。
@ConfigurationProperties(prefix = "custom.elasticsearch.settings")
public class ElasticsearchProperties {
private String hostName;
private Integer port;
private String clusterName;
private Integer poolSize;
private String schema = "http";
... get set ignore ...
}
@ConfigurationProperties:注解把yml文件配置的属性映射到属性Bean。springBoot 从一开始就指定了默认找配置文件application.properties,在springBoot 我们知道配置文件可以使用.yml后缀作为属性配置文件,不过也会去找application.yml文件。还有在/config/application.yml。
如果自定义了一个属性配置文件,启动之后会找不到你的配置文件,需要通过 @PropertySource("classpath:/mailconfig.properties") 注解来指定你需要映射的配置文件。
@ConfigurationPropertiesBindingPostProcessor 会对标注 @ConfigurationProperties注解的Bean进行属性值的配置
创建自动装配类
一般每个 starter 都会至少有一个自动配置类
命名规则都是:xxxAutoConfiguration
例如RedisAutoConfiguration,SolrAutoConfiguration、KafkaAutoConfiguration
完全可以参考这些去写一个自动装配类
@Configuration
@EnableConfigurationProperties(ElasticsearchProperties.class)
public class YdElasticsearchAutoConfiguration {
private final ElasticsearchProperties elasticsearchProperties;
public YdElasticsearchAutoConfiguration(ElasticsearchProperties elasticsearchProperties){
this.elasticsearchProperties = elasticsearchProperties;
}
private RestHighLevelClient restHighLevelClient;
@Bean
@ConditionalOnMissingBean
public RestHighLevelClient getRestHighLevelClient(){
this.restHighLevelClient = createEsClient();
return this.restHighLevelClient;
}
public RestHighLevelClient createEsClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpPost(elasticsearchProperties.getHostName(),
elasticsearchProperties.getPort(),
elasticsearchProperties.getSchema()))
);
return client;
}
}
@Configuration 用于定义配置类,可代替xml配置文件,被注解的类内部包含有一个或多个被@Bean 注解的方法,这些方法将会被 AnnotationConfigApplicationContext 或AnnotationConfigWebApplicationContext 类进行扫描,并用于构建bean定义,来完成初始化Spring容器。
@EnableConfigurationProperties 注解spring官网是这样解释的:为带有 @ConfigurationProperties 注解的Bean提供有效的支持。提供一种方便的方式来将带有@ConfigurationProperties 注解的类注入为Spring容器的Bean。
@Bean 注解可以理解为spring的xml里面bean标签。主要用在@Configuration注解的类里,也可以用在@Component注解的类里。
@ConditionalOnMissingBean 注解表示当容器中没有这个Bean的时候进行自动配置,可以给该注解传入参数。
例如:@ConditionOnMissingBean(name = "example"),表示如果name为“example”的Bean存在,该注解所修饰的代码块不执行,也就是不注册Bean。
注意:springboot 会将开发者自己声明的Bean优先级提到最高。
SpringBoot内置条件注解
@ConditionalOnXxx 可以说是自动装配的关键。满足Xxx条件,才会被装配到容器
@ConditionalOnBean:当SpringIoc容器内,存在指定Bean才会执行的一个条件
@ConditionalOnClass:当类路径存在指定类才会执行的一个条件
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在时查找指定的位置
@ConditionalOnMissingBean:当SpringIoc容器内不存在指定Bean才会执行的一个条件
@ConditionalOnMissingClass:当类路径不存在指定class才会执行的一个
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件
@ConditionalOnProperty:指定的属性是否有值
@ConditionalOnResource:当类路径存在指定的配置文件才会指定的一个条件
@ConditionalOnSingleCandidate:当指定Bean在SpringIoc容器内只有一个,或者有多个但是指定首选的Bean
@ConditionalOnWebApplication:当前项目是Web项目的条件
以上注解都是元注解@Conditional演变而来的,根据不同的条件对应创建以上的具体条件注解
增加配置文件
在src/main/resources/META-INF/目录下新建配置文件spring.factories,并指定自动装配类路径
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.starter.elastic.YdElasticsearchAutoConfiguration
配置的结构形式是 K=V 形式,多个V时使用 ,\ 隔开
Key 是不可变的:org.springframework.boot.autoconfigure.EnableAutoConfiguration
Value 就是 xxxAutoConfiguration 自动装配的类。
spring.factories 这个文件目录需要手动创建
工作运行原理
@SpringBootApplication 注解类上有一个开启自动化配置的注解 @EnableAutoConfiguration 来完成自动化配置,在 @EnableAutoConfiguration 注解类通过 @import 注解来完成导入配置的功能,而 EnableAutoConfigurationImportSelector 内部则是使用了SpringFactoriesLoader.loadFactoryNames 方法进行扫描具有 META-INF/spring.factories 文件的jar包
简单说就是:
1)Spring Boot在启动时扫描项目所依赖的jar包,寻找包含 spring.factories 文件的jar包
2)读取spring.factories文件获取配置的自动配置类 XxxxAutoConfiguration
3)将自动配置类下满足条件(@ConditionalOnXxx) 的 @Bean 加载到Spring容器中
当使用的时候可以直接注入方式注入进来,因为该类已经在容器中了。
思而不学则殆