目录

springboot自定义starter

starter:场景启动器

如何自定义starter

依赖

这个场景需要使用到的依赖有哪些

自动配置

编写自动配置类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
@Configuration(proxyBeanMethods = false) // 指定这个类是一个配置类
@ConditionalOnWebApplication(type = Type.SERVLET) // 在指定条件成立的情况下自动配置类生效
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) // 指定自动配置类的顺序
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
      ValidationAutoConfiguration.class }) // 指定在哪个配置之后执行
public class WebMvcAutoConfiguration {
  
  @Bean
	@ConditionalOnMissingBean(FormContentFilter.class)
	@ConditionalOnProperty(prefix = "spring.mvc.formcontent.filter", name = "enabled", matchIfMissing = true)
  @EnableConfigurationProperties //让xxxProperties生效加入到容器中

将自动配置类放入spring.factories

自动配置类要能加载 将需要启动就加载的自动配置类,配置在META-INF/spring.factories

1
2
3
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\

模式

启动器模块是一个空 JAR 文件,仅提供辅助性依赖管理,这些依赖可能用于自动装配或者其他类库

xxx-starter -> xxx-starter-autoconfigurer

命名归约

推荐使用以下命名规约;

官方命名空间

  • 前缀:“spring-boot-starter-”
  • 模式:spring-boot-starter-模块名
  • 举例:spring-boot-starter-web、spring-boot-starter-actuator、spring-boot-starter-jdbc

自定义命名空间

  • 后缀:“-spring-boot-starter”
  • 模式:模块-spring-boot-starter
  • 举例:mybatis-spring-boot-starter

演示自定义starter

完整示例工程地址

  1. 创建一个maven空工程,Empty Project spring-boot-starter-demo

  2. 增加moudle eh-spring-boot-starter

    删除src文件夹

  3. 增加moudle,使用spring initializer eh-spring-boot-starter-autoconfigurer

    删除主程序、test文件夹、清空resources,删除test依赖和插件

  4. 增加测试moudle,使用spring initializer构建web应用, eh-test-spring-boot-starter

工程目录结构如下:

20201025152023

自动配置模块

pom.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?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.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.eh</groupId>
    <artifactId>eh-spring-boot-starter-autoconfigurer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eh-spring-boot-starter-autoconfigurer</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-starter-web</artifactId>
        </dependency>

        <!--导入配置文件处理器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>


</project>

HelloProperties.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package com.eh.starter;

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

@ConfigurationProperties(prefix = "eh.hello")
@Data
public class HelloProperties {
    private String prefix;
    private String suffix;
}

HelloService.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package com.eh.starter;

import lombok.Setter;

public class HelloService {
    @Setter
    private HelloProperties helloProperties;

    public String sayHello(String name) {
        return helloProperties.getPrefix() + "-" + name + helloProperties.getSuffix();
    }
}

HelloServiceAutoCofiguration.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.eh.starter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnWebApplication // web应用才生效
@EnableConfigurationProperties(HelloProperties.class)
public class HelloServiceAutoConfiguration {

    @Autowired
    private HelloProperties helloProperties;

    @Bean
    public HelloService helloService() {
        HelloService helloService = new HelloService();
        helloService.setHelloProperties(helloProperties);
        return helloService;
    }
}

spring.factories

在resources目录下新建META-INF目录,在该目录下新建spring.factories文件,添加如下内容

1
2
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.eh.starter.HelloServiceAutoConfiguration

启动器模块

只做依赖引入

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?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.eh</groupId>
    <artifactId>eh-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.eh</groupId>
            <artifactId>eh-spring-boot-starter-autoconfigurer</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

install

install到maven仓库中,先install autoconfigurer再install starter

使用

pom.xml 引入启动器坐标

1
2
3
4
5
<dependency>
    <groupId>com.eh</groupId>
    <artifactId>eh-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

application.properties 增加配置

1
2
eh.hello.prefix=EHPrefix
eh.hello.suffix=EHSuffix

HelloController.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.eh.ehtestspringbootstarer.controller;

import com.eh.starter.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @Autowired
    private HelloService helloService;

    /**
     * 测试:http://localhost:8080/
     * 结果:EHPrefix-davidEHSuffix
     * @return
     */
    @GetMapping("/")
    public String sayHello() {
        return helloService.sayHello("david");
    }
}

小结

  • HelloProperties从配置文件中读取属性配置到自己的类中
  • HelloService引入HelloProperties使用配置
  • HelloServiceAutoCofiguration将HelloService放入容器中
  • HelloServiceAutoCofiguration放在spring.factories里面,由springboot容器帮我们加载