Starter
实现自定义的spring-boot-starter
1. 目录结构
starter[项目名称]
-- src
-- main
-- java
-- package [项目包名]
-- EnableXXX.java
-- XXXMarkerConfiguration.java
-- XXXAutoConfiguration.java
-- XXXProperties.java
-- XXXService.java
-- resources
-- META-INF
-- additional-spring-configuration-metadata.json [application.properties/yml 自动提示]
-- spring.factories
-- test
-- java
-- resources
2. 依赖导入
使用maven或者gradle配置项目
使用gradle配置项目时build.gradle实现
buildscript {
ext {
springBootVersion = '2.0.1.RELEASE'
}
repositories {
maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'io.spring.dependency-management'
// 配置编码
compileJava.options.encoding = 'UTF-8'
// 配置java编译版本
sourceCompatibility = 1.8
targetCompatibility = 1.8
// 配置maven仓库
repositories {
maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
}
// 配置依赖
dependencies {
compile "org.springframework.boot:spring-boot-autoconfigure:2.0.1.RELEASE"
compile "org.springframework.boot:spring-boot-configuration-processor:2.0.1.RELEASE"
}
compileJava.dependsOn(processResources)
3. 代码实现
3.1 Enable形式实现自动加载
自定义注解, 启用配置项, 使用import导入配置类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(XXXMarkerConfiguration.class)
public @interface EnableXXX {
}
@Configuration
public class XXXMarkerConfiguration {
@Bean
public Marker markerBean() {
return new Marker();
}
class Marker {
}
}
重要: 通过@ConditionalOnBean(XXXMarkerConfiguration.Marker.class)配置, 程序在Application时配置 Enable注解后,自动加载自定义配置
@Configuration
@ConditionalOnBean(XXXMarkerConfiguration.Marker.class)
@EnableConfigurationProperties(XXXProperties.class)
public class XXXAutoConfiguration {
}
3.2 配置自定义属性
@Component
@ConfigurationProperties(prefix = "prefix")
public class XXXProperties {
// 属性key
private String key;
// 省略setter/getter方法
...
}
XXXService服务
@Component
public class XXXService {
@Autowired
private XXXProperties properties;
public String test(){
return properties.getKey();
}
}
在AutoConfiguration中配置自定义的Bean, 提供外部依赖使用
public class XXXAutoConfiguration {
@Bean
@ConditionalOnMissingBean(XXXService.class)
public XXXService xxxService(){
return new XXXService();
}
}
3.3 配置资源依赖文件
在META-INF目录下spring.factories这个properties文件中, 配置key为org.springframework.boot.autoconfigure.EnableAutoConfiguration,这样才会被springboot自动加载
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=package.XXXAutoConfiguration
配置属性文件自动提示, 通过添加additional-spring-configuration-metadata.json文件实现
{
"properties": [
{
"name": "prefix.key",
"type": "java.lang.String",
"sourceType": "package.XXXProperties",
"description": "key.",
"defaultValue": "default"
}
],
"hints": [
]
}
4. 示例
引入相关依赖
<dependency>
<groupId>xxxx</groupId>
<artifactId>xxx-spring-boot-starter</artifactId>
<version>xxx</version>
</dependency>
dependencies {
compile 'groupId:xxx-spring-boot-starter:xxx'
}
自动配置服务
@SpringBootApplication
@EnableXXX
public class Application {
@Autowired
private XXXService xxxService;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
5.注解说明
| 注解 | 说明 |
|---|---|
@ConditionalOnBean |
当容器中有指定的Bean的条件下 |
@ConditionalOnClass |
当类路径下有指定的类的条件下 |
@ConditionalOnExpression |
基于SpEL表达式作为判断条件 |
@ConditionalOnJava |
基于JVM版本作为判断条件 |
@ConditionalOnJndi |
在JNDI存在的条件下查找指定的位置 |
@ConditionalOnMissingBean |
当容器中没有指定Bean的情况下 |
@ConditionalOnMissingClass |
当类路径下没有指定的类的条件下 |
@ConditionalOnNotWebApplication |
当前项目不是Web项目的条件下 |
@ConditionalOnProperty |
指定的属性是否有指定的值 |
@ConditionalOnResource |
类路径下是否有指定的资源 |
@ConditionalOnSingleCandidate |
当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean |
@ConditionalOnWebApplication |
当前项目是Web项目的条件下 |