本文首发于我的网站,原文地址:www.javaadu.online/?p=535,如需转载,请注明出处java
在学习Spring Boot的过程当中,接触最多的就是starter。能够认为starter是一种服务——使得使用某个功能的开发者不须要关注各类依赖库的处理,不须要具体的配置信息,由Spring Boot自动经过classpath路径下的类发现须要的Bean,并织入bean。举个例子,spring-boot-starter-jdbc这个starter的存在,使得咱们只须要在BookPubApplication下用@Autowired
引入DataSource的bean就能够,Spring Boot会自动建立DataSource的实例。面试
这里咱们会用一个不太规范的starter展现Spring Boot的自动配置的运行原理。Spring Boot的自动配置、Command-line Runner一文中曾利用StartupRunner类在程序运行启动后首先查询数据库中书的数目,如今换个需求:在系统启动后打印各个实体的数量。spring
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<!-- version继承父模块的-->
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.9.3.RELEASE</version>
</dependency></dependencies>复制代码
package com.test.bookpubstarter.dbcount;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.repository.CrudRepository;
import java.util.Collection;
public class DbCountRunner implements CommandLineRunner {
protected final Logger logger = LoggerFactory.getLogger(DbCountRunner.class);
private Collection<CrudRepository> repositories;
public DbCountRunner(Collection<CrudRepository> repositories) {
this.repositories = repositories;
}
@Override
public void run(String... strings) throws Exception {
repositories.forEach(crudRepository -> {
logger.info(String.format("%s has %s entries",
getRepositoryName(crudRepository.getClass()),
crudRepository.count()));
});
}
private static String getRepositoryName(Class crudRepositoryClass) {
for (Class repositoryInterface : crudRepositoryClass.getInterfaces()) {
if (repositoryInterface.getName().startsWith("com.test.bookpub.repository")) {
return repositoryInterface.getSimpleName();
}
}
return "UnknownRepository";
}
}复制代码
package com.test.bookpubstarter.dbcount;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.repository.CrudRepository;
import java.util.Collection;
@Configuration
public class DbCountAutoConfiguration {
@Bean
public DbCountRunner dbCountRunner(Collection<CrudRepository> repositories) {
return new DbCountRunner(repositories);
}
}复制代码
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.test.bookpubstarter.dbcount.DbCountAutoConfiguration复制代码
<dependency>
<groupId>com.test</groupId>
<artifactId>db-count-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>复制代码
正规的starter是一个独立的工程,而后在maven中新仓库注册发布,其余开发人员就可使用你的starter了。数据库
常见的starter会包括下面几个方面的内容:后端
在应用程序启动过程当中,Spring Boot使用SpringFactoriesLoader类加载器查找org.springframework.boot.autoconfigure.EnableAutoConfiguration关键字对应的Java配置文件。Spring Boot会遍历在各个jar包种META-INF目录下的spring.factories文件,构建成一个配置文件链表。除了EnableAutoConfiguration关键字对应的配置文件,还有其余类型的配置文件:maven
Spring Boot的starter在编译时不须要依赖Spring Boot的库。这个例子中依赖spring boot并非由于自动配置要用spring boot,而仅仅是由于须要实现CommandLineRunner接口。ide
***本号专一于后端技术、JVM问题排查和优化、Java面试题、我的成长和自我管理等主题,为读者提供一线开发者的工做和成长经验,期待你能在这里有所收获。函数