在使用springboot的时候,只需要添加一些starter依赖,就能极大地简化开发操作,那么如何自定义一个starter?
创建简单的 starter 项目
这个项目不需要特别多的依赖,只需一个
1
| implementation("org.springframework.boot:spring-boot-autoconfigure")
|
编写service,这是我们需要自动配置的服务。
1 2 3 4 5 6 7 8 9 10
| public interface HelloService { String sayHello(); }
public class HelloServiceImpl implements HelloService { @Override public String sayHello() { return "hello world"; } }
|
编写配置文件
1 2 3 4 5 6 7 8 9
| @Configuration public class AutoConfiguration {
@Bean @ConditionalOnMissingBean public HelloService helloService() { return new HelloServiceImpl(); } }
|
接着在resources
文件夹下创建META-INF
文件夹,在文件夹中创建spring.factories
文件,文件内容为:
注意修改自己的包名
1
| org.springframework.boot.autoconfigure.EnableAutoConfiguration=net.peihuan.starterdemo.config.AutoConfiguration
|
代码编写完成了,现在需要发布 jar 包,这里我使用了nexus搭建的私有仓库。
修改build.gradle
文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| buildscript {
ext { springBootVersion = '2.1.8.RELEASE' }
dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } repositories { mavenLocal() maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' } } }
apply plugin: 'java' apply plugin: 'maven' apply plugin: 'eclipse' apply plugin: 'maven-publish'
apply plugin: 'io.spring.dependency-management'
group 'net.peihuan' version '0.0.5'
sourceCompatibility = 1.8
repositories { mavenLocal() maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' } }
dependencyManagement { imports { mavenBom "org.springframework.boot:spring-boot-dependencies:${springBootVersion}" } }
dependencies { implementation("org.springframework.boot:spring-boot-autoconfigure") }
task sourcesJar(type: Jar) { classifier = 'sources' from sourceSets.main.allJava }
task javadocJar(type: Jar) { classifier = 'javadoc' from javadoc.destinationDir }
publishing { publications { mavenJava(MavenPublication) { from components.java artifact sourcesJar artifact javadocJar groupId project.group artifactId project.name version project.version pom { name = project.name description = project.description } } } repositories { maven { def releasesRepoUrl = "http://repo.peihuan.net/repository/maven-releases/" def snapshotsRepoUrl = "http://repo.peihuan.net/repository/maven-snapshots/" url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl credentials { def nexusUsername = "your-username" def nexusPassword = "your-password" username nexusUsername password nexusPassword } } } }
|
如果发布出现一些奇怪的错误,检查下gradle版本,这里给出使用的
1 2 3 4 5
| distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists
|
你也可以发布到本地maven仓库,这样更简单。
创建测试项目引入starter
只需要在build.gradle
文件中添加自己的私有仓库地址和依赖即可。
修改一下入口,执行后能看到打印出了HelloService
对象的地址,所以自动配置成功了。
1 2 3 4 5 6 7 8
| @SpringBootApplication public class HelloWorldApplication {
public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(HelloWorldApplication.class, args); System.out.println(run.getBean(HelloService.class)); } }
|
为什么需要 spring.factories
starter为什么要添加 spring.factories 文件?可以试着删掉这个文件,然后添加一个主入口并执行
1 2 3 4 5 6 7 8 9 10
| @SpringBootApplication public class StarterDemoApplication {
public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(StarterDemoApplication.class, args); System.out.println(context.getBean(HelloService.class)); }
}
|
会发现没有了spring.factories
,依旧能打印出HelloService
对象的内存地址,自动装配了HelloService
实例。
既然如此,为什么还需要这个文件?删掉spring.factories
,打一个新jar包,测试项目引入新jar包后,运行后将无法自动装配这个类。具体原理可以看这篇文章spring源码阅读(二)——自动配置