Spring Boot Starter 开发指南
Spring Boot Starter是什么?
依赖管理是任何复杂项目的关键部分。以手动的方式来实现依赖管理不太现实,你得花更多时间,同时你在项目的其他重要方面能付出的时间就会变得越少。
Spring Boot starter 就是为了解决这个问题而诞生的。Starter POM 是一组方便的依赖描述符,您可以将其包含在应用程序中。您可以获得所需的所有 Spring 和相关技术的一站式服务,无需通过示例代码搜索和复制粘贴依赖。
揭开Spring Boot自动装配的神秘面纱
Auto Configuration 类
当Spring Boot启动时,它会在类路径中查找名为spring.factories
的文件。该文件位于META-INF
目录中。让我们看一下spring-boot-autoconfigure
项目中这个文件的片段:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
此文件定义了一些Spring Boot将尝试运行的自动装配类。例如以上的代码片段,Spring Boot将尝试运行RabbitMQ,Cassandra,MongoDB和Hibernate的所有配置类。这些类是否实际运行将取决于类路径上是否存在依赖类。例如,如果在类路径中找到MongoDB
的类,则将运行MongoAutoConfiguration
,并初始化所有与mongo相关的bean。此条件初始化由@ConditionalOnClass
注释启用。让我们看一下MongoAutoConfiguration
类的代码片段,看看它的用法:
@Configuration
@ConditionalOnClass(MongoClient.class)
@EnableConfigurationProperties(MongoProperties.class)
@ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDbFactory")
public class MongoAutoConfiguration {
// configuration code
}
如果存在MongoClient
类,将运行该自动装配类初始化MongoClient
相关bean。
在application.properties
自定义配置
Spring Boot使用一些预先配置的默认值初始化bean。要覆盖这些默认值,我们通常会在application.properties
文件中使用某个特定名称声明它们。Spring Boot容器会自动获取这些属性。
在MongoAutoConfiguration
的代码片段中,@EnableConfigurationProperties(MongoProperties.class)
表示,使用MongoProperties
类来声明自定义属性:
@ConfigurationProperties(prefix = "spring.data.mongodb")
public class MongoProperties {
private String host;
// other fields with standard getters and setters
}
@ConfigurationProperties(prefix = "spring.data.mongodb")
定义了配置前缀,我们可以在application.properties
这样来使用它:
spring.data.mongodb.host = localhost
这样,初始化的时候,localhost
将被注入到host
属性中
自定义Spring Boot Starter
Spring Boot自动装配虽然神奇,但是编写起来却异常简单,我们只需要按部就班的执行以下两个流程:
- 编写属性容器
*Properties
,并编写对应的*AutoConfiguration
自动装配类 - 一个pom文件,用于定义引入库和自动装配类的依赖项
概念解析
用于*Properties
的注解
@ConfigurationProperties(prefix = "spring.data.mongodb")
:用于指定配置前缀
用于*AutoConfiguration
的注解
- @Configuration:标记为配置类,由Spring容器初始化并接管
- @EnableConfigurationProperties:注入配置属性容器
- @ConditionalOnBean:条件装配
重点说下条件装配,以@ConditionalOnBean
为例,当Spring容器中存在指定Bean的时候装配
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class)
public @interface ConditionalOnBean{
//properties
}
@Conditional(OnBeanCondition.class)
指定了实现条件装配的逻辑代码
OnBeanCondition
声明如下:
class OnBeanCondition extends SpringBootCondition implements ConfigurationCondition{}
所以,我们自己也可以继承SpringBootCondition
并实现ConfigurationCondition
来自定义条件装配注解。
比较常用的几个条件装配注解:
- @ConditionalOnBean:当Spring容器中存在指定Bean时装配
- @ConditionalOnClass:当存在指定Class时装配
- @ConditionalOnMissingBean:当Spring容器中不存在指定Bean时装配
- @ConditionalOnMissingClass:当不存在指定Class时装配
小试牛刀
我们将自动配置模块称为
greeter-spring-boot-autoconfigure
。该模块将有两个主要类,即GreeterPropertie
s,它将通过application.properties
文件和GreeterAutoConfiguartion
设置自定义属性,并为greeter库创建bean。
准备,创建假想的一个第三方工程:Greet
public class Greeter {
private GreetingConfig greetingConfig;
public Greeter(GreetingConfig greetingConfig) {
this.greetingConfig = greetingConfig;
}
public String greet(LocalDateTime localDateTime) {
String name = greetingConfig.getProperty(USER_NAME);
int hourOfDay = localDateTime.getHour();
if (hourOfDay >= 5 && hourOfDay < 12) {
return String.format("Hello %s, %s", name, greetingConfig.get(MORNING_MESSAGE));
} else if (hourOfDay >= 12 && hourOfDay < 17) {
return String.format("Hello %s, %s", name, greetingConfig.get(AFTERNOON_MESSAGE));
} else if (hourOfDay >= 17 && hourOfDay < 20) {
return String.format("Hello %s, %s", name, greetingConfig.get(EVENING_MESSAGE));
} else {
return String.format("Hello %s, %s", name, greetingConfig.get(NIGHT_MESSAGE));
}
}
public String greet() {
return greet(LocalDateTime.now());
}
}
public class GreeterConfigParams {
public static final String USER_NAME = "user.name";
public static final String MORNING_MESSAGE = "morning.message";
public static final String AFTERNOON_MESSAGE = "afternoon.message";
public static final String EVENING_MESSAGE = "evening.message";
public static final String NIGHT_MESSAGE = "night.message";
}
public class GreetingConfig extends Properties {
private static final long serialVersionUID = 5662570853707247891L;
}
编写Properties和AutoConfiguration:
@ConfigurationProperties(prefix = "gcdd1993.greeter")
public class GreeterProperties {
private String userName;
private String morningMessage;
private String afternoonMessage;
private String eveningMessage;
private String nightMessage;
// getter and setter
}
@Configuration
@ConditionalOnClass(Greeter.class)
@EnableConfigurationProperties(GreeterProperties.class)
public class GreeterAutoConfiguration {
@Autowired
private GreeterProperties greeterProperties;
@Bean
@ConditionalOnMissingBean
public GreetingConfig greeterConfig() {
String userName = greeterProperties.getUserName() == null
? System.getProperty("user.name")
: greeterProperties.getUserName();
GreetingConfig greetingConfig = new GreetingConfig();
greetingConfig.put(USER_NAME, userName);
if (greeterProperties.getMorningMessage() != null) {
greetingConfig.put(MORNING_MESSAGE, greeterProperties.getMorningMessage());
}
if (greeterProperties.getAfternoonMessage() != null) {
greetingConfig.put(AFTERNOON_MESSAGE, greeterProperties.getAfternoonMessage());
}
if (greeterProperties.getEveningMessage() != null) {
greetingConfig.put(EVENING_MESSAGE, greeterProperties.getEveningMessage());
}
if (greeterProperties.getNightMessage() != null) {
greetingConfig.put(NIGHT_MESSAGE, greeterProperties.getNightMessage());
}
return greetingConfig;
}
@Bean
@ConditionalOnMissingBean
public Greeter greeter(GreetingConfig greetingConfig) {
return new Greeter(greetingConfig);
}
}
然后在src/main/resources/META-INF
目录下创建spring.factories
文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.gcdd.autoconfigure.GreeterAutoConfiguration
测试一下:
- 创建配置文件
application.properties
:
gcdd1993.greeter.userName=gcdd1993
gcdd1993.greeter.eveningMessage=good evening
- 使用Greeter bean
@SpringBootApplication
public class GreeterSampleApplication implements CommandLineRunner {
@Autowired
private Greeter greeter;
public static void main(String[] args) {
SpringApplication.run(GreeterSampleApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
String message = greeter.greet();
System.out.println(message);
}
}
执行main方法,将会输出一行:
Hello gcdd1993, good evening
为配置类添加提示
我们知道,在Idea中,编写配置文件的时候,有智能提示
其实这不是Idea搞的鬼,是由META-INF/spring-configuration-metadata.json
文件配置好的,Idea只是负责解析这个文件,提供我们智能化的提示信息。
想要达到这个目的很简单,添加依赖org.springframework.boot:spring-boot-configuration-processor
就行了。
Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
Gradle
compile group: 'org.springframework.boot', name: 'spring-boot-configuration-processor', version: '2.1.6.RELEASE'
总结
以上就是Spring Boot Starter
的全部内容了,如果要发布到maven仓库,供别人使用,可以使用mvn install
打包发布至maven仓库。
Spring Boot Starter 开发指南的更多相关文章
- spring boot starter开发
作为公司的技术保障部,一直承担着技术方向的把控,最近公司准备全面转入spring boot的开发.所以我们部门也一直在调研相关的技术知识点: 使用springboot开发应用已经有一段时间了,我们都沉 ...
- 最详细的自定义Spring Boot Starter开发教程
1. 前言 随着Spring的日渐臃肿,为了简化配置.开箱即用.快速集成,Spring Boot 横空出世. 目前已经成为 Java 目前最火热的框架了.平常我们用Spring Boot开发web应用 ...
- 从零开始开发一个Spring Boot Starter
一.Spring Boot Starter简介 Starter是Spring Boot中的一个非常重要的概念,Starter相当于模块,它能将模块所需的依赖整合起来并对模块内的Bean根据环境( 条件 ...
- Spring Boot Starter 介绍
http://www.baeldung.com/spring-boot-starters 作者:baeldung 译者:http://oopsguy.com 1.概述 依赖管理是任何复杂项目的关键部分 ...
- spring -boot s-tarter 详解
Starter POMs是可以包含到应用中的一个方便的依赖关系描述符集合.你可以获取所有Spring及相关技术的一站式服务,而不需要翻阅示例代码,拷贝粘贴大量的依赖描述符.例如,如果你想使用Sprin ...
- spring boot + vue + element-ui全栈开发入门——spring boot后端开发
前言 本文讲解作为后端的spring boot项目开发流程,如果您还不会配置spring boot环境,就请点击<玩转spring boot——快速开始>,如果您对spring boot还 ...
- SpringBoot 之Spring Boot Starter依赖包及作用
Spring Boot 之Spring Boot Starter依赖包及作用 spring-boot-starter 这是Spring Boot的核心启动器,包含了自动配置.日志和YAML. spri ...
- Spring Boot Starter列表
转自:http://blog.sina.com.cn/s/blog_798f713f0102wiy5.html Spring Boot Starter 基本的一共有43种,具体如下: 1)spring ...
- 手把手教你定制标准Spring Boot starter,真的很清晰
写在前面 我们每次构建一个 Spring 应用程序时,我们都不希望从头开始实现具有「横切关注点」的内容:相反,我们希望一次性实现这些功能,并根据需要将它们包含到任何我们要构建的应用程序中 横切关注点 ...
随机推荐
- [Jinja2]本地加载html模板
import os from jinja2 import Environment, FileSystemLoader env = Environment(loader=FileSystemLoader ...
- 初见shell
在写了一段时间的java后,发现要一次性执行多个java很麻烦,因此想到了用shell脚本去调用.但是因为之前没有学过shell,所以一切都是重新开始.在此,简单的记录下意思的基础性知识. 参数相关的 ...
- Entity Framework 实体状态
从今天开始我们开始讲解EF中的实体状态和数据操作,这篇文章先讲解实体状态. 我们通过前面的学习,知道EF通过上下位负责跟踪实体的状态,实体状态的位置是在命名空间 System.Dat.Entity 里 ...
- Spring Boot从入门到精通(二)配置GitHub并上传Maven项目
简单介绍一下GitHub,它是一个面向开源及私有软件项目的托管平台,因为只支持git作为唯一的版本库格式进行托管,故名GitHub. GitHub于2008年4月10日正式上线,除了Git代码仓库托管 ...
- [Effective Java 读书笔记] 第二章 创建和销毁对象 第五条
第五条 避免创建不必要的对象 书中一开始举例: String s = new String("stringette"); // don't do this //应该使用下面,只会创 ...
- Hexo搭建静态博客踩坑日记(二)
前言 Hexo搭建静态博客踩坑日记(一), 我们说到利用Hexo快速搭建静态博客. 这节我们就来说一下主题的问题与主题的基本修改操作. 起步 chrome github hexo git node.j ...
- 图像分割:Semantic/Instance/Panoramic Segmentation
一. 背景介绍 语义分割(Semantic Segmentation):对一张图片上的所有像素点进行分类,同一物体的不同实例不需要单独分割出来. 实例分割(Instance Segmentation) ...
- 分享8个laravel模型时间戳使用技巧
默认情况下,Laravel Eloquent 模型默认数据表有 created_at 和 updated_at 两个字段.当 然,我们可以做很多自定义配置,实现很多有趣的功能.下面举例说明. 1. 禁 ...
- java 入门如何设计类
2019/12/24 | 在校大二上学期 | 太原科技大学 初学java后,我们会发现java难点不在于Java语法难学,而是把我们挂在了如何设计类的“吊绳”上了.这恰恰也是小白 ...
- [.NET][C#] C#中的时间戳
Unix时间戳(Unix timestamp),或称Unix时间(Unix time).POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年1月1日0时0分0秒( ...