Spring Boot:定制自己的starter
在学习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类在程序运行启动后首先查询数据库中书的数目,现在换个需求:在系统启动后打印各个实体的数量。
How Do 新建一个模块db-count-starter,然后修改db-count-starter模块下的pom文件,增加对应的库。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新建包结构com/test/bookpubstarter/dbcount,然后新建DbCountRunner类,实现CommandLineRunner接口,在run方法中输出每个实体的数量。
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"; }增加自动配置文件DbCountAutoConfiguration
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); }在src/main/resources目录下新建META-INF文件夹,然后新建spring.factories文件,这个文件用于告诉Spring Boot去找指定的自动配置文件,因此它的内容是
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.test.bookpubstarter.dbcount.DbCountAutoConfiguration在之前的程序基础上,在顶层pom文件中增加starter的依赖
dependency groupId com.test /groupId artifactId db-count-starter /artifactId version 0.0.1-SNAPSHOT /version /dependency把StartupRunner相关的注释掉,然后在main函数上右键Run BookPubApplication.main(...),可以看出我们编写的starter被主程序使用了。
自己的starter简单演示.png
正规的starter是一个独立的工程,然后在maven中新仓库注册发布,其他开发人员就可以使用你的starter了。
常见的starter会包括下面几个方面的内容:
自动配置文件,根据classpath是否存在指定的类来决定是否要执行该功能的自动配置。 spring.factories,非常重要,指导Spring Boot找到指定的自动配置文件。 endpoint:可以理解为一个admin,包含对服务的描述、界面、交互(业务信息的查询) health indicator:该starter提供的服务的健康指标在应用程序启动过程中,Spring Boot使用SpringFactoriesLoader类加载器查找org.springframework.boot.autoconfigure.EnableAutoConfiguration关键字对应的Java配置文件。Spring Boot会遍历在各个jar包种META-INF目录下的spring.factories文件,构建成一个配置文件链表。除了EnableAutoConfiguration关键字对应的配置文件,还有其他类型的配置文件:
org.springframework.context.ApplicationContextInitializer org.springframework.context.ApplicationListener org.springframework.boot.SpringApplicationRunListener org.springframework.boot.env.PropertySourceLoader org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider org.springframework.test.contex.TestExecutionListenerSpring Boot的starter在编译时不需要依赖Spring Boot的库。这个例子中依赖spring boot并不是因为自动配置要用spring boot,而仅仅是因为需要实现CommandLineRunner接口。
两个需要注意的点@ConditionalOnMissingBean的作用是:只有对应的ban在系统中都没有被创建,它修饰的初始化代码块才会执行,用户自己手动创建的bean优先;
spring.factories:由Spring Boot触发探测classpath目录下的类,进行自动配置; @Enable:有时需要由starter的用户触发*查找自动配置文件的过程。
Spring boot 使用 ON DUPLICATE KEY UPDATE属性控制版本 更新数据不成功 如果更新不成功会报下面的错误(此错误是自定义的): The data you want to update has been updated by another user. Please reopen and try again! 一、主要按下面的流程检查: 1、检查数据库的段alastupdatetime定义 2、检查.xml的alastupdatetime 3、要更新数据的主键是否在同一个updateByBatch中的List中重复出现
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载
相关文章
- Spring MVC更多家族成员--国际化视图与LocalResolver---10
- Spring Boot框架基础概览
- Spring Boot利用AOP获取用户操作实现日志记录
- Spring boot集成knife4j
- Spring Boot 中使用@KafkaListener并发批量接收消息[通俗易懂]
- Spring Boot辅助功能之内嵌服务器【Tom Cat】
- Spring Boot+MyBatis Plus+JWT 问卷系统!开源!
- 不会前端没事,用GWT Boot和Spring Boot构建Web程序
- spring boot整合jsp的时候访问页面错误日志:Path with "WEB-INF" or "META-INF":
- spring注解开发AnnotationConfigApplicationContext的使用
- SpringBoot:模块探究之spring-boot-starters
- Spring Boot | 集成MapStruct实现不同类型Java对象间的自动转换
- Security安全认证 | Spring Boot如何集成Security实现安全认证
- Spring Boot 源码解读与原理剖析|文末赠书
- Spring Cloud Stream与RabbitMQ的集成
- Spring Cloud Task 核心组件-Task Repository
- 将 Spring Cloud Task 集成到 Spring Boot 应用中
- 如何使用 Arthas 定位 Spring Boot 接口超时
- Spring面试题和答案汇总详解编程语言
- Spring Boot 配置加载顺序详解编程语言
- Spring Boot(十三):spring boot小技巧详解编程语言
- 使用Spring boot 嵌入的tomcat不能启动: Unregistering JMX-exposed beans on shutdown详解编程语言
- Spring getConnectionProperties方法:获取数据库连接属性
- Maven搭建SSH(Struts2+Spring+Hibernate)框架入门教程(附带实例)
- Spring Boot 2.0 的快速入门(图文教程)