如何自定义spring boot starter项目

如何自定义spring boot starter项目

问题

Spring Boot 通过很多 starter 依赖,提供很多常用组件的默认配置,大大地简化开发时,集成第三方组件时所需的配置;

我们如何实现一个自定义的 starter 项目,以便简化我们开发时引入内部相关组件所需的配置。

方案

自定义 starter 的步骤如下:

  1. 创建项目
  2. 引入必要依赖
  3. 自定义 Properties 类
  4. 定义核心服务类
  5. 定义自动配置类
  6. 打包发布
  7. 创建用于测试 starter 的项目

1.创建项目

命名规范:

  • Spring 官方的 starter 通常被命名为 spring-boot-starter-(名字) ,如 “spring-boot-starter-web” 。
  • Spring 官方建议非官方的 starter 命名遵循 “(名字)-spring-boot-starter” 的格式,如"myxxx-spring-boot-starter" 。

可参考《如何快速构建一个Spring Boot项目》。

1.构建SpringBoot项目1

项目坐标

    <groupId>com.chen.solution.starter</groupId>
    <artifactId>demo-spring-boot-starter</artifactId>
    <version>1.0.0</version>

2.引入必要依赖

自定义的 starter 是不能有启动入口的,即它只能作为工具类。所以,不要把自定义的 pom.xml 写成一个可启动的项目。

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
  • :假如 Project A 的某个依赖 D 添加了true,当其它项目通过pom依赖Project A的时候,D不会被传递依赖进来。

3.自定义 Properties 类

在使用 starter 时,可以在 application.properties 文件中配置参数,以覆盖默认值。

在自定义 starter 时,可以根据需要来配置 Properties 类,以保存配置信息,例:

@ConfigurationProperties(
    prefix = "spring.chen.starter"
)
@Getter
@Setter
public class StarterProps {

    private String word = "default";
    
}

4.定义核心服务类

每个 starter 都需要有自己的功能,所以需要定义服务类。

public class MyStarter {
    private StarterProps starterProps;

    public MyStarter(){

    }

    public MyStarter(StarterProps starterProps){
        this.starterProps = starterProps;
    }

    public String hello(){
        String msg = "hello:"+ starterProps.getWord();
        System.out.println(msg);
        return msg;
    }
}

5.定义自动配置类

每个 starter 一般至少有一个自动配置类,命名规则为 “名字+AutoConfiguration”。

@Configuration
@EnableConfigurationProperties(StarterProps.class)
// 在类路径 classpath 下有指定的类的情况下进行自动配置
@ConditionalOnClass(MyStarter.class)
// 属性 matchIfMissing=true 时进行自动配置
@ConditionalOnProperty(prefix="spring.chen.starter",value="enabled",matchIfMissing = true)
public class StarterServiceAutoConfiguration {

    @Resource
    private StarterProps starterProps;

    @Bean
    // 在容器中没有指定 Bean 的情况下自动配置 MyStarter 类
    @ConditionalOnMissingBean(MyStarter.class)
    public MyStarter myStarter(){
        MyStarter myStarter = new MyStarter(starterProps);
        return myStarter;
    }

}

在 resources 文件夹下新建目录 META-INF ,在目录中新建 spring.factories 文件,并且在 spring.factories 中配置 AutoConfiguration ,如下所示:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.chen.solution.starter.demo.config.StarterServiceAutoConfiguration

多个类,使用逗号隔开,例:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
...

6.打包发布

打成 Jar 包,发布到本地私有仓库或 Maven 私有仓库中。

使用命令 mvn clean install 发布到本地仓库。

使用 mvn clean deploy 发布到私有仓库。


7.创建用于测试 starter 的项目

创建测试项目,引入自定义的 starter 项目依赖:

    <dependency>
        <groupId>com.chen.solution.starter</groupId>
        <artifactId>demo-spring-boot-starter</artifactId>
        <version>1.0.0</version>
    </dependency>

指定配置参数

# 自定义 starter 配置
spring.chen.starter.word=world

执行测试用例,使用 starter

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoSpringBootStarterTestApplicationTests {

    @Resource
    private MyStarter myStarter;

    @Test
    public void contextLoads() {
        myStarter.hello();
    }
}

常用注解说明

  • 注解@EnableConfigurationProperties :让使用了 @ConfigurationProperties 注解的类生效,并且将该类注入到 IOC 容器中,交由 IoC 容器进行管理 。

  • 注解@ConditionalOnClass :是 Spring Boot 实现自动配置的重要支撑之一。其用途是判断当前 classpath 下是否存在指定类,若是则将当前的配置装载入Spring IoC 容器。

  • 注解@ConditionalOnProperty :在 Spring Boot 中有时候需要控制配置类是否生效,可以使用 @ConditionalOnProperty 注解来控制 @Configuration 是否生效。属性 matchIfMissing=true 时进行自动配置 。

    • name和value不能同时存在.也不能同时不存在, 两者只能存在一个。
    • 如果havingValue存在, 则跟havingValue的值进行比较, 相同返回true, 不同则返回false
    • 如果没有指定havingValue, 则用prefix + name 或者prefix + value获取配置项的值, 然后跟 "false"字符串比较, 相同返回false, 不同返回true
      • 相同: 即配置项值为false时, 例spring.chen.starter.enabled=false, 此时是不加载被修饰的类或方法。
      • 不同: 即配置项值为非false的任何值, 例spring.chen.starter.enabled=true / spring.chen.starter.enabled=123 / spring.chen.starter.enabled= 等, 都是返回true. 此时加载被修饰的类或方法。
    • 在配置matchIfMissing后, 如果prefix + name 或者prefix + value 都不存在, 则以matchIfMissing的值为准.
      • matchIfMissing = true, 则加载
      • matchIfMissing = false, 则不加载
  • 注解@ConditionalOnMissingBean:根据当前环境或者容器情况来动态注入bean,要配合@Bean使用

    • @ConditionalOnMissingBean Spring 容器中不存在该类型Bean时起效;作用:判断当前需要注入 Spring 容器中的bean的实现类是否已经含有,有的话不注入,没有就注入。
    • @ConditionalOnBean Spring 容器中存在该类型Bean时起效;作用:判断当前需要注册的bean的实现类否被 Spring 管理,如果被管理则注入,反之不注入。
  • 注解@Conditional:作用:Spring4 推出了 @Conditional 注解,方便程序根据当前环境或者容器情况来动态注入bean,按照一定的条件进行判断,满足条件给容器注册bean。

代码仓库

https://gitee.com/chentian114/solution-springboot

公众号

知行chen

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值