创建一个springboot starter页面

环境

java1.8

springboot 2.7.1

pom.xml文件

项目目录

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 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.7.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.yestea</groupId>
    <artifactId>digest-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>digest-spring-boot-starter</name>
    <description>digest-spring-boot-starter</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.17.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

<!--    <build>-->
<!--        <plugins>-->
<!--            <plugin>-->
<!--                <groupId>org.springframework.boot</groupId>-->
<!--                <artifactId>spring-boot-maven-plugin</artifactId>-->
<!--            </plugin>-->
<!--        </plugins>-->
<!--    </build>-->

</project>

application.properties

yaml 复制代码
spring.application.name=digest-spring-boot-starter
digest.type=md5

service目录

Digest.java 接口

java 复制代码
package com.yestea.service;

public interface Digest {
    String digest(String raw);
}

impl目录接口实现类

Md5Digest.java

java 复制代码
package com.yestea.service.impl;

import com.yestea.service.Digest;
import org.apache.commons.codec.digest.DigestUtils;

public class Md5Digest implements Digest {
    public String digest(String raw) {
        System.out.println("使用MD5加密");
        return DigestUtils.md5Hex(raw);
    }
}

ShaDigest.java实现接口

java 复制代码
package com.yestea.service.impl;

import com.yestea.service.Digest;
import org.apache.commons.codec.digest.DigestUtils;

public class ShaDigest implements Digest {
    public String digest(String raw) {
        System.out.println("使用SHA1加密");
        return DigestUtils.sha1Hex(raw);
    }
}

config目录setting.java 读取application.properties配置信息加载到类

java 复制代码
package com.yestea.config;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

//@Component
@ConfigurationProperties(prefix = "digest")
public class setting {
    private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

config.java

java 复制代码
package com.yestea.config;

import com.yestea.service.Digest;
import com.yestea.service.impl.Md5Digest;
import com.yestea.service.impl.ShaDigest;
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(setting.class)
public class config {
    @Bean
    @ConditionalOnProperty(prefix = "digest", name = "type", havingValue = "md5")
    public Digest Md5Digest(){
       return new Md5Digest();
    }
    @Bean
    @ConditionalOnProperty(prefix = "digest", name = "type", havingValue = "sh")
    public Digest ShaDigest(){
        return new ShaDigest();
    }
}

EnableConfigurationProperties

html 复制代码
@EnableConfigurationProperties 是 Spring Boot 提供的一个注解,主要作用如下:
启用配置属性功能
用于启用 @ConfigurationProperties 注解的类,使其能够从配置文件中自动绑定属性值
只有在添加了 @EnableConfigurationProperties 后,@ConfigurationProperties 注解的类才会被 Spring 容器管理
自动注册配置属性类
将指定的 @ConfigurationProperties 类注册为 Spring Bean
无需手动使用 @Component 或 @Configuration 

DigestSpringBootStarterApplication.java

java 复制代码
package com.yestea;

import com.yestea.config.setting;
import com.yestea.service.Digest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import javax.annotation.Resource;


//@SpringBootApplication
public class DigestSpringBootStarterApplication {


    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DigestSpringBootStarterApplication.class, args);
        setting bean = run.getBean(setting.class);
        System.out.println(bean);
//        Digest bean1 = run.getBean(Digest.class);
//        System.out.println(bean1);
    }

}

注意打包成jar包时候@SpringBootApplication必须删除不然会提示有两个无法执行

下面是重头戏,引用时候必须知道从什么地方读取

resources目录下创建META-INF创建spring.factories文件

java 复制代码
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.yestea.config.config

为什么是这个目录这个需要看源码

点开SpringBootApplication注解可以看到

java 复制代码
public @interface SpringBootApplication {
    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    Class<?>[] exclude() default {};

    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    String[] excludeName() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "nameGenerator"
    )
    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}
java 复制代码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

AutoConfigurationImportSelector.class注解

摘抄一部分内容可以看到

java 复制代码
    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = new ArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()));
        ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).forEach(configurations::add);
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

接下来进行maven clean install 本地仓库打包之后另外项目引入pom.xml文件

测试代码

java 复制代码
package com.yestea;

import com.yestea.service.Digest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class MybatisPlus01test3 {
    @Autowired
    private Digest digest;
    @Test
    public void test01(){
        System.out.println(digest.digest("123456"));
    }
}

执行结果

python 复制代码
使用SHA1加密
7c4a8d09ca3762af61e59520943dc26494f8941b