4.2创建自定义Spring Boot自动配置Starter
这个章节,我们将会创建我们自己的Spring Bootstarter,这个starter会包含一个自动依赖在我们的项目中。
在第二章节中, 我们已经知道如何去创建数据库属性对象。让我们创建一个简单的starter,这个starter会创建另外一个CommandLineRunner,然后收集Repository的实例并且打印所有的实例。
4.2.1代码实现
1.首先我们创建一人新文件夹db-count-starter在项目根目录下。
2.在文件夹db-count-starter下创建一份settings.grale文件,添加以下内容。
include 'db-count-starter'
3.在db-count-starter文件夹下创建build.gradle的文件,然后添加如下的代码。
apply plugin: 'java' |
4.接着,我们在fb-count-starter下创建这个目录结构src/main/java/org/test/bookpubstarter/dbcount
5.在新创建的文件下面,让我们添加实现接口CommandLineRunner文件,名称叫做DbCountRunner.java.
public class DbCountRunner implements CommandLineRunner { protected final Log logger = LogFactory.getLog(getClass()); private Collection<CrudRepository> repositories;
public DbCountRunner(Collection<CrudRepository> repositories) { this.repositories = repositories; }
@Override public void run(String... args) 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( "org.test.bookpub.repository")) { return repositoryInterface.getSimpleName(); } } return "UnknownRepository"; }
} |
6.我们创建一个DbCountAutoConfiguration.java来实现DbCountRunner。
@Configuration public class DbCountAutoConfiguration { @Bean public DbCountRunner dbCountRunner(Collection<CrudRepository> repositories) { return new DbCountRunner(repositories); } } |
7.我们需要告诉Spring Boot我们新创建的JAR包含自动装配的类。我们需要在db-count-starter/src/main下创建resources/META-INF文件夹。
8.在resources/META-INF下创建spring.factories文件,添加如下内容。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.test |
9.在主项目的build.gradle下添加如下代码
compile project(':db-count-starter') |
10.启动项目,你将会看到控制台的信息下:
2020-04-05 INFO org.test.bookpub.StartupRunner : Welcome to the Book Catalog System! 2020-04-05 INFO o.t.b.dbcount.DbCountRunner : AuthorRepository has 1 entries 2020-04-05 INFO o.t.b.dbcount.DbCountRunner : PublisherRepository has 1 entries 2020-04-05 INFO o.t.b.dbcount.DbCountRunner : BookRepository has 1 entries 2020-04-05 INFO o.t.b.dbcount.DbCountRunner :ReviewerRepository has 0 entries 2020-04-05 INFO org.test.bookpub.BookPubApplication : Started BookPubApplication in 8.528 seconds (JVM running for 9.002) 2020-04-05 INFO org.test.bookpub.StartupRunner : Number of books: 1 |
4.2.2代码说明
因为Spring Boot的starter是分隔的,独立的包,仅仅是添加更多的类到我们已经存在的项目资源中,而不会控制更多。为了独立技术,我们的选择很少,创建分开的配置在我们项目中或创建完全分开的项目。更好的方法是通过创建项目文件夹去转换们的项目到Gradel Multi-Project Build和子项目依赖于根目录到build.gradle。Gradle实际是创建JAR的包,但是我们不需要放入到任何地方,仅仅通过compile project(‘:db-count-starter’)来包含。
Spring Boot Auto-Configuration Starter并没有做什么,而是Spring Java Configuration类注释了@Configuration和代表性的spring.factories文件在META-INF的文件夹下。
当应用启动时,Spring Boot使用SpringFactoriesLoader,这个类是Spring Core中的,目的是为了获得Spring Java Configuration,这些配置给了org.springframework.boot.autoconfigure.EnableAutoConfiguration。这样之下,这些调用会收集spring.factories文件下的所有jar包或其它调用的路径和成分到应用的上下文的配置中。除此之了EnableAutoConfiguration,我们可以定义其它的关键接口使用,这些可以自动初始化在启动期间与如下的调用相似:
org.springframework.context.ApplicationContextInitializer |
具有讽刺的是,Spring Boot Starter并不需要依赖Spring Boot的包,因为它编译时间上的依赖。如果我们看DbCountAutoConfiguation类,我们不会看到任何来自org.springframework.book的包。这仅仅的原因是我们的DbCountRunner实现了接口org.sprigframework.boot.CommandLineRunner.