虽然SpringBoot官方给我提供了许多starter启动器,但是我们在工作开发中还是避免不了自定义启动器来简化我们的开发。

为此我们通过对SpringBoot自动配置原理的分析,我们要有

  1. 场景启动器starter
  2. 自动配置包autoconfigure

starter中没有任何代码,只是引入了当前场景我们所需的依赖。和最核心的一个自动配置包。

环境搭建

首先我们创建一个空项目boot-09-customer-starter

image-20210320175840299

自动配置包

创建一个自动配置包kylin-hello-spring-boot-starter-autoconfigure模块。

image-20210320181039646

image-20210320181112148

这里我们没有其他功能,所以没有导入其他的启动器。

启动器

接着在该项目中,创建一个启动器模块kylin-hello-spring-boot-starter。这里我们就直接创建一个Maven项目就行了(因为并不要写代码),只需引入相关依赖就行了。

image-20210320180729603

image-20210320180824676

爆红是因为我事先已经创好了。

接着我们要在我们的启动器中导入我们的自动配置包依赖。

image-20210320181457794

1
2
3
4
5
<dependency>
<groupId>com.kylin</groupId>
<artifactId>kylin-hello-spring-boot-starter-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

此后别人只要引入我们的场景启动器,就会自动把自动配置包给一同引入。

编写自动配置包

自动配置包的代码编写,首先我们把一些没有的依赖给删除掉。

image-20210320181746612

只留下了spring-boot-starter依赖。

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

接着删除了主程序类,和Test包。(用不到)

service

我们编写一个HelloService

image-20210320182017193

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 默认不用注入到Spring容器中
*/
public class HelloService {

@Autowired
HelloProperties helloProperties;

public String sayHello(String userName) {
return helloProperties.getPrefix() + ":" + userName + ":" + helloProperties.getSuffix();
}

}

properties

我们创建一个HelloProperties类,通过配置文件kylin.hello属性绑定给他赋值,被HelloService给使用。

image-20210320182216785

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@ConfigurationProperties("kylin.hello")
public class HelloProperties {

private String prefix;
private String suffix;

public String getPrefix() {
return prefix;
}

public void setPrefix(String prefix) {
this.prefix = prefix;
}

public String getSuffix() {
return suffix;
}

public void setSuffix(String suffix) {
this.suffix = suffix;
}
}

auto

创建一个HelloServiceAutoConfiguration自动配置类。

image-20210320182417405

1
2
3
4
5
6
7
8
9
10
11
@Configuration
@EnableConfigurationProperties(HelloProperties.class)
public class HelloServiceAutoConfiguration {

@ConditionalOnMissingBean(HelloService.class)//容器中没有时生效
@Bean
public HelloService helloService() {
return new HelloService();
}

}

值得注意的是我们的HelloService类是没有主动注册到Spring容器中的。所以当容器中没有该类时,自动注入。

META-INF

通过对SpringBoot自动配置原理的分析。我们要在该包下创建一个META-INF包,在包下创建一个spring.factories文件

image-20210320182741036

1
2
3
#Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.kylin.auto.HelloServiceAutoConfiguration

给该属性org.springframework.boot.autoconfigure.EnableAutoConfiguration赋值为我们自动配置类的位置。

Install本地仓库

接着我们先后给自动配置包,和启动器。clean,install到我们本地的Maven仓库中。

image-20210320183010419

image-20210320183113253

测试

创建一个boot-09-hello-testSpringboot项目,导入web启动器。

image-20210320183333025

导入了我们自定义的启动器kylin-hello-spring-boot-starter

接着我们编写一个controller。

image-20210320183452637

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RestController
public class HelloController {


@Autowired
HelloService helloService;

@GetMapping("/hello/{username}")
public String sayHello(@PathVariable String username) {

return helloService.sayHello(username);
}

}

给properties赋值。通过hello-kylin

image-20210320183531052

1
2
kylin.hello.prefix=KYLIN
kylin.hello.suffix=666

运行主程序,访问http://localhost:8080/hello/kylin

image-20210320183641502