三、SpringBoot自定义Starter

目录

1 项目工程的创建

1.1 创建Empty Project

1.2 创建starter模块

1.3 创建autoconfigure模块

1.4 实现HelloWorld自动配置

1.5 创建spring.factories文件

2 helloworld自动配置的使用

3 元数据的配置

3.1 Group属性

3.2 Property属性

3.3 hints属性

3.4 配置元数据


在前面两章《一、SpringBoot入门》《二、SpringBoot自动配置原理》我们对如何创建一个SpringBoot项目、SpringBoot的运行原理以及自动配置等都有了一定的了解。如果我们系统中也想要拥有自动配置的功能,可以自己编写一个starter (启动器),想想就觉得很酷,因为这意味着我们不仅有自己定义的自动配的功能,而且具有更通用的耦合度更低的配置。

还是以第一章开头的简单功能为例:浏览器发送sayHello请求,服务器接受请求并处理,响应Hello 。

首先我们看下工程结构:

helloworld-spring-boot-starter-autoconfigure(以下简称autoconfigure):该模块用来实现Helloworld的自动配置功能,它的打包方式为jar;

helloworld-spring-boot-starter(以下简称starter):该模块的打包方式是jar,依赖autoconfigure模块,它不写任何代码,只做自动配置包的自动引入,如果要使用helloworld自动配置功能,只要在pom文件中引入starter模块即可:

<dependency>
    <groupId>com.seagetech.spring.boot</groupId>
    <artifactId>helloworld-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

 

1 项目工程的创建

 

1.1 创建Empty Project

(1)、新建一个空的项目,如下图,点击Next

 

(2)、输入项目名称以及选择项目存放路径,点击Finish

 

 

 

1.2 创建starter模块

(1)、在1.1节中新建的空项目基础上新建一个Module

 

 

(1)、选择Maven,点击Next

 

 

(2)、输入GroupId、ArtifactId和Version信息,点击Finish

 

 

(3)、由于这个模块只做自动配置包的引入,所有删除src下的包,最终项目结构如下:

 

 

pom.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.seagetech.spring.boot</groupId>
    <artifactId>helloworld-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</project>

 

1.3 创建autoconfigure模块

 

(1)、按1.2节第(1)步,新建一个Module,并选择Spring Initializr,点击Next

 

 

(2)、输入项目相关信息,如下图所示:

 

 

(3)、选择依赖,我们这里只选择web场景的依赖,点击Next

 

 

(4)、默认,不需要改动,点击Finish

 

 

 

(4)、删除SpringBoot自动创建的主配置类、resources下所有文件(夹)以及test文件夹,最终项目结构如下:

 

pom.xml(已删除test测试模块的自动配置包以及build下的maven插件)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>com.seagetech.spring.boot</groupId>
   <artifactId>helloworld-spring-boot-starter-autoconfigure</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>

   <name>helloworld-spring-boot-starter-autoconfigure</name>
   <description>Demo project for Spring Boot</description>

   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.1.0.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
   </properties>

   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
   </dependencies>
</project>

(5)、在1.2节创建的helloworld-spring-boot-starter的pom下模块引入本节创建的autoconfigure模块:

<dependency>
    <groupId>com.seagetech.spring.boot</groupId>
    <artifactId>helloworld-spring-boot-starter-autoconfigure</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

1.4 实现HelloWorld自动配置

(1)、在helloworld包下新建HelloWorldProperties类,作为配置类,目的是后面使用这个自动配置,直接可以在application.properties文件中配置:

package com.seagetech.spring.boot.helloworld;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * HelloWorld属性配置类
 * @auther: wangzb
 * @date: 2018/11/13 22:21
 */
@ConfigurationProperties(prefix = "hello")
public class HelloWorldProperties {
    /**
     * 打招呼的内容,默认为“World!”
     */
    private String msg = "World!";

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

(2)、新建HelloWorldService接口,并实现:

接口:
/**
 * @auther: wangzb
 * @date: 2018/11/13 22:28
 */
public interface HelloWorldService {
    /**
     * 打招呼方法
     * @param name 人名,向谁打招呼使用
     * @return
     */
    String sayHello(String name);
}
实现类:
/**
 * @auther: wangzb
 * @date: 2018/11/13 22:33
 */
@Component
public class HelloWorldServiceImpl implements HelloWorldService{

    @Autowired
    private HelloWorldProperties helloWorldProperties;

    /**
     * 打招呼方法
     *
     * @param name 人名,向谁打招呼使用
     * @return
     */
    @Override
    public String sayHello(String name) {
        return "Hello " + name + " " + helloWorldProperties.getMsg();
    }
}

(3)、新建HelloWorldAutoConfiguration配置类

/**
 * @auther: wangzb
 * @date: 2018/11/13 22:37
 */
//定义为配置类
@Configuration
//在web条件下成立
@ConditionalOnWebApplication
//启用HelloWorldProperties配置功能,并加入到IOC容器中
@EnableConfigurationProperties({HelloWorldProperties.class})
//导入HelloWorldService组件
@Import(HelloWorldServiceImpl.class)
public class HelloWorldAutoConfiguration {
}

 

1.5 创建spring.factories文件

《二、SpringBoot自动配置原理》中,我们提到@EnableAutoConfiguration 的关键功能是使用SpringFactoriesLoader.loadFactoryNames方法来扫描具有META-INF/spring.factories文件的jar包,这样我们的自动配置类才能生效,所以我们在autoconfigure模块的resources下创建META-INF/spring.factories文件:

在spring.factories中写入:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.seagetech.spring.boot.helloworld.HelloWorldAutoConfiguration

 

2 helloworld自动配置的使用

创建好helloworld自动配置项目后,接下来就是使用了,我们在idea中使用install将1节中创建好的starter/autoconfigure模块打包到本地maven创库,然后在 《一、SpringBoot入门》章节创建的sping-boot-demo项目中使用,在其pom文件中引入:

<dependency>
    <groupId>com.seagetech.spring.boot</groupId>
    <artifactId>helloworld-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

在主配置类路径下创建HelloWorldController :

package com.seagetech.springbootdemo;

import com.seagetech.spring.boot.helloworld.HelloWorldService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @auther: wangzb
 * @date: 2018/11/17 11:17
 */
@Controller
public class HelloWorldController {

    @Autowired
    private HelloWorldService helloWorldService;

    @RequestMapping(value = "/sayHello")
    public String sayHello(String name){
        return helloWorldService.sayHello(name);
    }
}

启动项目,在浏览器输入:http://localhost:8080/sayHello?name=wangzb,浏览器返回:

Hello wangzb World!

看到默认返回的消息是World!,如果在application.properties文件中配置如下属性:

hello.msg = 你好

我们在重启项目,重复以上步骤,浏览器响应:

Hello wangzb 你好

 

3 元数据的配置

到目前为止,helloworld的自动配置功能已实现,并且正确使用了,但还有一点不够完美,如果你也按上面步骤实现了自己的helloworld自动配置,在application.properties中配置hello.msg属性时,你会发现并没有提示你有关该配置的信息,但是如果你想配置tomcat端口时,输入server.port是有提示的:

 

 

这种功能我们如何做呢,我们打开 章节下载的《spring-boot-reference.pdf》文件,在目录中找到“Appendix B. Configuration Metadata(附录B.配置元数据)”,下面我们使用谷歌来翻译下相关原文:

Spring Boot jars include metadata files that provide details of all supported configuration properties.The files are designed to let IDE developers offer contextual help and “code completion” as users are working with application.properties or application.yml files.

Spring Boot jar包含元数据文件,提供所有支持的配置属性的详细信息。这些文件旨在让IDE开发人员使用application.properties或application.yml文件像用户一样提供上下文帮助和“代码完成”

......

B.1 Metadata Format

Configuration metadata files are located inside jars under META-INF/spring-configurationmetadata.json They use a simple JSON format with items categorized under either “groups” or “properties” and additional values hints categorized under "hints", as shown in the following example:  

B.1 元数据格式

配置元数据文件位于META-INF / spring-configuration-metadata.json下的jar中。它们使用简单的JSON格式,其中的项目分类为“groups”或“properties”和其他值提示分类在“hints”下。

  ....

看看它的例子:

{"groups": [{
    "name": "server",
    "type": "org.springframework.boot.autoconfigure.web.ServerProperties",
    "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
...
],
"properties": [{
    "name": "server.port",
    "type": "java.lang.Integer",
    "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},{
    "name": "server.address",
    "type": "java.net.InetAddress",
    "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
...
],
"hints": [{
    "name": "spring.jpa.hibernate.ddl-auto",
    "values": [{
         "value": "none",
         "description": "Disable DDL handling."
     },{
         "value": "validate",
         "description": "Validate the schema, make no changes to the database."
     },{
         "value": "update",
         "description": "Update the schema if necessary."
     }]
]}

 

关groups、properties、hints使用。

 

3.1 Group属性

“groups”中包含的JSON对象可以包含下表中显示的属性:

 

3.2 Property属性

properties数组中包含的JSON对象可由以下属性构成:

 

3.3 hints属性

hints数组中包含的JSON对象可以包含以下属性:

每个"hints"元素的values属性中包含的JSON对象可以包含下表中描述的属性:

 每个"hints"元素的providers属性中的JSON对象可以包含下表中描述的属性:

 

3.4 配置元数据

所以如果想有更好的用户体验,可以为我们自定义的starter配置元数据,下面就为HelloWorld配置元数据。

在META-INF下创建spring-configuration-metadata.json文件:

 

 

在文件中输入如下内容:

{
  "hints":[{
    "name":"hello.msg",
    "values":[{
      "value":"你好",
      "description":"中文方式打招呼"
    },{
      "value":"Hi",
      "description":"英文方式打招呼"
    }]
  }],
  "groups":[
    {
      "sourceType": "com.seagetech.spring.boot.helloworld.HelloWorldProperties",
      "name": "hello",
      "type": "com.seagetech.spring.boot.helloworld.HelloWorldProperties"
    }],
  "properties":[
    {
      "sourceType": "com.seagetech.spring.boot.helloworld.HelloWorldProperties",
      "name": "hello.msg",
      "type": "java.lang.String",
      "description": "打招呼的内容",
      "defaultValue": "Worlds"
    }]
}

 

然后将autoconfigure模块重新打包,接下来就是在spring-boot-demo项目中使用,如下图所示,就有了属性的提示:

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值