美文网首页Spring Boot&Spring Cloudspringmvc学习Model
快速开发一个自定义Spring Boot Starter,并使用

快速开发一个自定义Spring Boot Starter,并使用

作者: 简单的土豆 | 来源:发表于2017-03-23 11:02 被阅读12543次

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

    好,开始,先创建一个Maven项目并引入依赖,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.example</groupId>
        <artifactId>example-spring-boot-starter</artifactId>
        <version>1.0-SNAPSHOT</version>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-autoconfigure</artifactId>
            </dependency>
        </dependencies>
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <!-- Import dependency management from Spring Boot -->
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>1.5.2.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    </project>
    

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

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

    public class ExampleService {
    
        private String prefix;
        private String suffix;
    
        public ExampleService(String prefix, String suffix) {
            this.prefix = prefix;
            this.suffix = suffix;
        }
        public String wrap(String word) {
            return prefix + word + suffix;
        }
    }
    

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

    @ConfigurationProperties("example.service")
    public class ExampleServiceProperties {
        private String prefix;
        private String suffix;
        //省略 getter setter
    

    重点,编写AutoConfigure

    @Configuration
    @ConditionalOnClass(ExampleService.class)
    @EnableConfigurationProperties(ExampleServiceProperties.class)
    public class ExampleAutoConfigure {
    
        @Autowired
        private ExampleServiceProperties properties;
    
        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnProperty(prefix = "example.service",value = "enabled",havingValue = "true")
        ExampleService exampleService (){
            return  new ExampleService(properties.getPrefix(),properties.getSuffix());
        }
    
    }
    

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

    • @ConditionalOnClass,当classpath下发现该类的情况下进行自动配置。
    • @ConditionalOnMissingBean,当Spring Context中不存在该Bean时。
    • @ConditionalOnProperty(prefix = "example.service",value = "enabled",havingValue = "true"),当配置文件中example.service.enabled=true时。

    更多相关注解,建议阅读官方文档该部分

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

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.autocinfigure.ExampleAutoConfigure
    

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


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

    引入example-spring-boot-starter依赖

     <dependency>
        <groupId>com.example</groupId>
        <artifactId>example-spring-boot-starter</artifactId>
        <version>1.0-SNAPSHOT</version>
     </dependency>
    

    创建application.properties,进行配置

    example.service.enabled=true
    example.service.prefix=####
    example.service.suffix=@@@@
    

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

    @SpringBootApplication
    @RestController
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
        @Autowired
        private ExampleService exampleService;
    
        @GetMapping("/input")
        public String input(String word){
            return exampleService.wrap(word);
        }
    
    }
    

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


    总结下Starter的工作原理

    1. Spring Boot在启动时扫描项目所依赖的JAR包,寻找包含spring.factories文件的JAR包
    2. 根据spring.factories配置加载AutoConfigure
    3. 根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context

    相关文章

      网友评论

      • alexxiyang:目前为止看到最简单最好的教程,美中不足的地方是没有把最终的pom.xml贴出来,完全的小白可能不知道还需要引入spring-boot-starter-web 或者得从SPRING INITIALIZR新建一个任务出来,才能使用example-spring-boot-starter。
      • e73f581586a3:看过一样摸一样的文章,就是输出改了一下:sweat_smile:
      • 萧忆情_912e:你好, 请问一下, 我使用的gradle来做,starter写好后通过gradle install发布到本地仓库。然后再起一个项目来使用,但是在depency里面 unable to resolve 自己添加的那个starterd。请问可能是什么原因呢? 我看用户下面的.m2里面的文件夹下面也确实有自己写的starter的jar包
      • 热心市民小陈:写得不错,简单易懂
      • 张张张大炮:谢谢您的分享,我遇到这样一个问题,在新项目中无法自动注入自己导入的starter里面的类,写怎么处理呢。。。
        张张张大炮: @张张张大炮 当我在加入了componentscan注解后自动注入便成功了,那我之前创建starter时所写在spring.factories文件里的配置其实是并没有起到作用的
      • 阿呆少爷:非常棒的一个例子👍
        要测试本地的jar包,pom.xml指定systemPath到jar包地址就好。

        <dependency>
        <groupId>com.henshao</groupId>
        <artifactId>example-spring-boot-starter</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>system</scope>
        <systemPath>/Users/henshao/Java/example-starter/target/example-spring-boot-starter-1.0-SNAPSHOT.jar</systemPath>
        </dependency>
        简单的土豆::smile: 好的,多谢
      • zxcvbnmzsedr::fearful: 那注解的话改怎么做啊
        简单的土豆:@zxcvbnmzsedr 使用@ConditionalOnBean注解 声明在存在哪个annotation的时候进行自动配置。
      • e69e49efbdb3:不错。。加油
        简单的土豆:@IceMimosa 谢谢

      本文标题:快速开发一个自定义Spring Boot Starter,并使用

      本文链接:https://www.haomeiwen.com/subject/scfanttx.html