拒绝花里胡哨,极简springboot starter自定义及原理

SpringBoot针对日常企业应用场景提供了各种spring-boot-starter依赖模块,所有这些依赖模块都遵循着约定俗成的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。SpringBoot通过AutoConfiguration模块自动装配官方(以spring-boot-starter-xxx方式命名)、第三方以及自定义(以xxx-spring-boot-starter方式命名)的starter.

当我们向其他项目提供jar包时,可自定义为starter,SpringBoot项目即可像自动加载spring-boot-starter-jdbc、spring-boot-starter-web等一样自动加载您的starter,下面即为一个最简单的自定义starter例子和原理介绍:

1. Pom依赖



    4.0.0

    com.zhangwei
    demo-spring-boot-starter
    1.0-SNAPSHOT

    
        org.springframework.boot
        spring-boot-starter-parent
        2.0.0.RELEASE
    

    
        1.8
    

    
        
            org.springframework.boot
            spring-boot-configuration-processor
            true
        

        
            org.springframework.boot
            spring-boot-autoconfigure
        


            org.projectlombok
            lombok
            1.18.8
        
    

其中spring-boot-starter-parent是springboot starter的父级依赖,统一封装了自定义starter所需的依赖和插件;

spring-boot-configuration-processor是springboot提供的工具包,用于编译期给标注了@ConfigurationProperties的配置类生成元数据信息,当在properties文件中配置相关属性时,就会根据元数据给出相应提示;

spring-boot-autoconfigure是springboot的自动装配模块,这里主要提供了自定义starter所需的注解,springboot会根据这些标记的注解完成自动装配逻辑;

lombok:非必须,其作用是帮助在编译时自动为属性生成getter/setter方法,减少代码量。

2. 定义一个配置信息实体类

package com.zhangwei;

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

@ConfigurationProperties(prefix = "demo")
@Data
public class DemoProperties {
    private String name = "zhangwei";
    private String city = "beijing";
}

其中@ConfigurationProperties可以把相同前缀的配置信息映射到实体类中的属性。

3. 定义一个Service

package com.zhangwei;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

@EnableConfigurationProperties(DemoProperties.class)
public class DemoService {

    @Autowired
    private DemoProperties demoProperties;

    public String say() {
        return "name:" + demoProperties.getName() + ",city:" + demoProperties.getCity();
    }
}

其中@EnableConfigurationProperties(xxx.class),用于开启属性配置类,并将该类加入spring容器,但是前提条件是spring能够发现DemoService类。

4. 重点:配置META-INF/spring.factories文件

在resources目录下新建META-INF/spring.factories文件,并配置:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.zhangwei.DemoService

springboot在启动时,借助@EnableAutoConfiguration中@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器,即会从classpath中搜索所有META-INF/spring.factories配置文件,并将其中org.spring-framework.boot.autoconfigure.EnableAutoConfiguration对应的配置项通过反射(Java Reflection)实例化为对应的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。自动配置的幕后英雄SpringFactoiesLoader是属于Spring框架私有的一种扩展方案(类似于Java的SPI方案java.util.ServiceLoader),其主要功能就是从指定的配置文件META-INF/spring.factories加载配置。

SPI,全称Service Provider Interface,是一种服务发现机制。它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。这一机制为很多框架扩展提供了可能,比如在Dubbo、JDBC中都使用到了SPI机制。

5. 测试验证

将自定义的demo-spring-boot-starter通过maven命令mvn clean install -U打成jar包,并安装在本地,在另一web项目中引入该jar包,依赖坐标如下:


    com.zhangwei
    demo-spring-boot-starter
    1.0-SNAPSHOT

编写测试用的controller如下:

@Controller
@RequestMapping("/")
public class IndexController {

    @Autowired
    private DemoService demoService;

    @RequestMapping("/")
    @ResponseBody
    public Result index() {
        return new Result(200, demoService.say());
    }
}

配置文件如下:

demo.name=lisi
demo.city=wuhan

访问controller,如下:

拒绝花里胡哨,极简springboot starter自定义及原理_第1张图片

 

你可能感兴趣的:(java,spring,boot,java,spring)