springboot 之 自定义starter

为什么要自定义starter

实现功能插件热插拔,随用随配置即可。

自定义starter步骤

  1. 引入对应的依赖
  2. 编写实现类
  3. 编写配置文件读取类 
  4. 编写自动装配类
  5. 编写默认的配置文件
  6. 在resources/META-INF/spring.factories 中配置我们的自动装配类

具体实现过程

1.pom配置文件

不需要springboot-boot-starter插件,没必要导入其他包。

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>helloworld-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>helloworld-spring-boot-starter</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>

<!--   编译命令,在命令行输入以下命令:     mvn clean install -Dmaven.test.skip=true-->

2.读取配置文件类

package com.example.helloworldspringbootstarter.properties;/*
 *create by test on 2019/12/12
 *
 *Remark:
 *
 */

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

@ConfigurationProperties(prefix = "spring.person")
public class PersonProperties {
    // 姓名
    private String name;
    // 年龄
    private int age;
    // 性别
    private String sex = "M";

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getSex() {
        return sex;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

3.服务类

package com.example.helloworldspringbootstarter.service;/*
 *create by test on 2019/12/12
 *
 *Remark:
 *
 */

import com.example.helloworldspringbootstarter.properties.PersonProperties;

public class PersonService {

    private PersonProperties properties;

    public PersonService() {
    }

    public PersonService(PersonProperties properties) {
        this.properties = properties;
    }

    public void sayHello(){
        System.out.println("大家好,我叫: " + properties.getName() + ", 今年" + properties.getAge() + "岁"
                + ", 性别: " + properties.getSex());
    }
}

4.自动配置类

package com.example.helloworldspringbootstarter.autoconfig;/*
 *create by test on 2019/12/12
 *
 *Remark:
 *
 */

import com.example.helloworldspringbootstarter.properties.PersonProperties;
import com.example.helloworldspringbootstarter.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(PersonProperties.class)
@ConditionalOnClass(PersonService.class)
@ConditionalOnProperty(prefix = "spring.person", value = "enabled", matchIfMissing = true)
public class PersonServiceAutoConfiguration {

    @Autowired
    private PersonProperties properties;

    @Bean
    @ConditionalOnMissingBean(PersonService.class)  // 当容器中没有指定Bean的情况下,自动配置PersonService类
    public PersonService personService(){
        PersonService personService = new PersonService(properties);
        return personService;
    }
}

 

 

5.手动创建文件夹和文件

src/main/resources/META-INF/spring.factories

文件内容:

#自动配置类的路径
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.helloworldspringbootstarter.autoconfig.PersonServiceAutoConfiguration

6. 当前项目路径下执行:mvn clean install

7.测试,创建新项目,导入starter信息

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

8.配置application.properties

spring.person.name=helloword
spring.person.age=30
spring.person.sex=WOMAN

9.测试代码

@SpringBootTest
class TestStartarApplicationTests {
    @Autowired
    private PersonService personService;

    @Test
    void test(){
        personService.sayHello();
    }
}

10.结果

 

Starter原理

  1. Spring Boot在启动时扫描项目所依赖的JAR包,寻找包含spring.factories文件的JAR包,
  2. 然后读取spring.factories文件获取配置的自动配置类AutoConfiguration
  3. 然后将自动配置类下满足条件(@ConditionalOnXxx)的@Bean放入到Spring容器中(Spring Context)
  4. 这样使用者就可以直接用来注入,因为该类已经在容器中了

部分注解说明

  • @EnableConfigurationProperties(XxxProperties.class) 注解的作用是使@ConfigurationProperties注解生效。如果只配置@ConfigurationProperties注解,在IOC容器中是获取不到properties配置文件转化的bean的
  • @ConfigurationProperties: 注解主要用来把properties配置文件转化为对应的XxxProperties来使用的,并不会把该类放入到IOC容器中,如果想放入到容器中可以在XxxProperties上使用@Component来标注,也可以使用@EnableConfigurationProperties(XxxProperties.class)统一配置到Application上来,这种方式可以在Application上来统一开启指定的属性,这样也没必要在每个XxxProperties上使用@Component

       其他注解可以自己查找

源代码:

https://download.csdn.net/download/u013919153/12028730

本文参考:

https://blog.csdn.net/vbirdbest/article/details/79863883

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值