暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SpringBoot自定义starter

程序员小阳的代码人生 2018-04-02
189

1.前言

我们都知道Spring Boot由众多Starter组成,随着版本的推移Starter家族成员也与日俱增。在传统Maven项目中通常将一些层、组件拆分为模块来管理,以便相互依赖复用,在Spring Boot项目中我们则可以创建自定义Spring Boot Starter来达成该目的。

2.实现

好,开始,先创建一个Maven项目并引入依赖,pom.xml如下,供参考~

  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <project xmlns="http://maven.apache.org/POM/4.0.0"

  3.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  4.         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  5.    <modelVersion>4.0.0</modelVersion>

  6.    <groupId>com.example</groupId>

  7.    <artifactId>example-spring-boot-starter</artifactId>

  8.    <version>1.0-SNAPSHOT</version>

  9.    <dependencies>

  10.        <dependency>

  11.            <groupId>org.springframework.boot</groupId>

  12.            <artifactId>spring-boot-autoconfigure</artifactId>

  13.        </dependency>

  14.    </dependencies>

  15.    <dependencyManagement>

  16.        <dependencies>

  17.            <dependency>

  18.                <!-- Import dependency management from Spring Boot -->

  19.                <groupId>org.springframework.boot</groupId>

  20.                <artifactId>spring-boot-dependencies</artifactId>

  21.                <version>1.5.2.RELEASE</version>

  22.                <type>pom</type>

  23.                <scope>import</scope>

  24.            </dependency>

  25.        </dependencies>

  26.    </dependencyManagement>

  27. </project>

这里说下artifactId的命名问题,Spring 官方 Starter通常命名为spring-boot-starter-{name}如 spring-boot-starter-web, Spring官方建议非官方Starter命名应遵循{name}-spring-boot-starter的格式。

这里讲一下我们的Starter要实现的功能,很简单,提供一个Service,包含一个能够将字符串加上前后缀的方法String wrap(String word)。

  1. public class ExampleService {


  2.    private String prefix;

  3.    private String suffix;


  4.    public ExampleService(String prefix, String suffix) {

  5.        this.prefix = prefix;

  6.        this.suffix = suffix;

  7.    }

  8.    public String wrap(String word) {

  9.        return prefix + word + suffix;

  10.    }

  11. }

前缀、后缀通过读取application.properties(yml)内的参数获得

  1. @ConfigurationProperties("example.service")

  2. public class ExampleServiceProperties {

  3.    private String prefix;

  4.    private String suffix;

  5.    //省略 getter setter

重点,编写ExampleAutoConfigure类

  1. @Configuration

  2. @ConditionalOnClass(ExampleService.class)//当classpath下发现该类的情况下进行自动配置

  3. @EnableConfigurationProperties(ExampleServiceProperties.class)

  4. public class ExampleAutoConfigure {

  5.    @Autowired

  6.    private ExampleServiceProperties properties;


  7.    @Bean

  8.    @ConditionalOnMissingBean // 当Spring Context中不存在该Bean时

  9.    @ConditionalOnProperty(prefix = "example.service",value = "enabled",havingValue = "true")//当配置文件中example.service.enabled=true时

  10.    ExampleService exampleService (){

  11.        return  new ExampleService(properties.getPrefix(),properties.getSuffix());

  12.    }


  13. }

解释下用到的几个和Starter相关的注解:

@ConditionalOnClass,当classpath下发现该类的情况下进行自动配置。 @ConditionalOnMissingBean,当Spring Context中不存在该Bean时。 @ConditionalOnProperty(prefix = "example.service",value = "enabled",havingValue = "true"),当配置文件中example.service.enabled=true时。 更多相关注解,建议阅读官方文档该部分。

最后一步,在resources/META-INF/下创建spring.factories文件,内容供参考下面~

  1. org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.yangyang.springboot.example.autoconfigure.ExampleAutoConfigure

OK,完事,运行 mvn:install打包安装,一个Spring Boot Starter便开发完成了。如果你需要该Starter的源代码,点这里。

创建一个Spring Boot项目来 试试~

引入example-spring-boot-starter依赖

  1. <dependency>

  2.    <groupId>com.example</groupId>

  3.    <artifactId>example-spring-boot-starter</artifactId>

  4.    <version>1.0-SNAPSHOT</version>

  5. </dependency>

创建application.properties,进行配置

  1. example.service.enabled=true

  2. example.service.prefix=####

  3. example.service.suffix=@@@@

创建一个简单的Spring Web Application,注入Starter提供的ExampleService看它能否正常工作~

  1. @SpringBootApplication

  2. @RestController

  3. public class Application {


  4.    public static void main(String[] args) {

  5.        SpringApplication.run(Application.class, args);

  6.    }


  7.    @Autowired

  8.    private ExampleService exampleService;


  9.    @GetMapping("/input")

  10.    public String input(String word){

  11.        return exampleService.wrap(word);

  12.    }


  13. }

启动Application,访问/input接口试试看~

3.总结下Starter的工作原理

  • Spring Boot在启动时扫描项目所依赖的JAR包,寻找包含spring.factories文件的JAR包

  • 根据spring.factories配置加载AutoConfigure类

  • 根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context

参考文章:https://www.jianshu.com/p/45538b44e04e


欢迎关注我的公众号,获取更多文章,并与我交流沟通。


文章转载自程序员小阳的代码人生,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论