1、概述
starter:
- 这个场景需要使用到的依赖是什么?
- 如何编写自动配置?
@Configuration //指定该类是一个配置类
@ConditionalOnXXX //在指定条件成立的情况下自动配置类生效
@AutoConfigureOrder //指定自动配置类的顺序
@AutoConfigureAfter //指定自动配置类的顺序
@Bean //给容器中添加组件
@ConfigurationProperties(prefix = "") //结合相关的xxxProperties类来绑定相关的配置
@EnableConfigurationProperties //让xxxProperties生效加入到容器中
- 自动配置类要能加载,必须将标注@Configuration的自动配置类放在classpath下META-INF/spring.factorys中
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\xxxxxxxxxxxxx
-
启动器模块是一个空JAR文件,仅提供辅助性的依赖管理,这些依赖可能用于自动装配或者其他类库
-
命名规则,推荐使用以下命名规则
-
官方命名空间
-前缀:spring-boot-starter-
-模式:spring-boot-starter-模块名
-举例:spring-boot-starter-web,spring-boot-starter-acutator
-
自定义命名空间
-后缀:-spring-boot-starter
-模式:模块名-spring-boot-starter
-举例:mybatis-spring-boot-starter
-
2、官方文档介绍
Under the hood, auto-configuration is implemented with standard `@Configuration` classes. Additional `@Conditional` annotations are used to constrain when the auto-configuration should apply. Usually, auto-configuration classes use `@ConditionalOnClass`and `@ConditionalOnMissingBean` annotations. This ensures that auto-configuration applies only when relevant classes are found and when you have not declared your own `@Configuration`.
在后台,自动配置是通过标准@Configuration类实现的
其它@Conditional批注用于约束何时应应用自动配置
通常,自动配置类使用@ConditionalOnClass和@ConditionalOnMissingBean批注
这样可以确保仅当找到相关的类并且没有声明自己的@Configuration时,自动配置才起用
You can browse the source code of spring-boot-autoconfigure
to see the @Configuration
classes that Spring provides (see the META-INF/spring.factories
file).
您可以浏览spring-boot-autoconfigure的源代码以查看Spring提供的@Configuration类(请参阅META-INF / spring.factories文件)
Spring Boot checks for the presence of a META-INF/spring.factories
file within your published jar. The file should list your configuration classes under the EnableAutoConfiguration
key, as shown in the following example:
Spring Boot检查发布的jar中是否存在META-INF / spring.factories文件。
该文件应在EnableAutoConfiguration键下列出您的配置类,如以下示例所示:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration
You can use @AutoConfigureAfter
or @AutoConfigureBefore
annotations if your configuration needs to be applied in a specific order. For example, if you provide web-specific configuration, your class may need to be applied after WebMvcAutoConfiguration
.
如果需要按特定顺序应用配置,则可以使用@AutoConfigureAfter或@AutoConfigureBefore批注
例如,如果您提供特定于Web的配置,则可能需要在WebMvcAutoConfiguration之后应用您的类
3、自定义starter
3.1、新建工程
新建一个空工程,在工程中新建两个模块
模块一:noox-spring-boot-starter
该模块(启动器)只用来做依赖管理与依赖引入的,依赖于自动配置
模块二:noox-spring-boot-starter-autoconfigure
该模块用来做我们的自动配置
然后再starter的pom.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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>top.noox</groupId>
<artifactId>noox-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 启动器 -->
<dependencies>
<!-- 引入自动配置模块 -->
<dependency>
<groupId>top.noox</groupId>
<artifactId>noox-spring-boot-starter-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
自动配置模块的依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
3.2、编写服务场景
假设有这么一个场景,编写一个HelloService类,里面有一个sayHello方法,传入一个名字,返回Hello信息
package top.noox;
public class HelloService {
private HelloProperties helloProperties;
//Getter与Setter省略
//前后缀可配置
public String sayHello(String name) {
return helloProperties.getPrefix() + name + helloProperties.getSuffix();
}
}
但是打招呼的信息是可配置的,于是把所有可配置的属性绑定在HelloProperties类中
package top.noox;
import org.springframework.boot.context.properties.ConfigurationProperties;
//与配置文件application.yml中所有的以noox.hello打头的配置绑定
@ConfigurationProperties(prefix = "noox.hello")
public class HelloProperties {
private String prefix;
private String suffix;
//Getter与Setter省略
}
我们要让它起效,就要在写一个自动配置类HelloServiceAutoConfiguration
package top.noox;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
@Configuration //标注该类是一个配置类
@ConditionalOnWebApplication //在web环境下自动配置类才会生效
@EnableConfigurationProperties(HelloProperties.class) //让指定的属性文件生效(加入容器)
public class HelloServiceAutoConfiguration {
//或者也可以选择直接@Autowired
private HelloProperties helloProperties;
//构造函数注入,当自动配置类只有一个构造时候这个autowired可以省略
public HelloServiceAutoConfiguration(HelloProperties helloProperties) {
this.helloProperties = helloProperties;
}
@Bean //给容器中添加一个HelloService组件
public HelloService getHelloService() {
HelloService helloService = new HelloService();
helloService.setHelloProperties(helloProperties);
return helloService;
}
}
但是,要让这个HelloServiceAutoConfiguration自动配置类能生效,还得在类路径下写一个文件夹spring.factories
在spring.factories文件夹中把我们springboot启动时要加载的我们的自动配置类全部配置上去
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
top.noox.HelloServiceAutoConfiguration
到此我们的自动配置模块就已经写完了,这个自动配置类给我们容器中会添加HelloService组件,而HelloService组件里面用到的属性都是跟HelloProperties绑定的,而且我们也配置好了我们的自动配置类是启动时候生效的,我们的starter模块也已经引入了我们的自动配置模块
目录结构:
3.3、安装到maven仓库
接下来将这两个模块安装到maven仓库中
注意要先安装自动配置模块,因为启动器模块依赖了该模块
4、测试
4.1、创建测试工程
使用spring initializer创建一个只带web模块的工程
4.2、引入坐标依赖
然后再项目中引入我们的starter依赖(GAV坐标)
<dependency>
<groupId>top.noox</groupId>
<artifactId>noox-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
可以看到我们的模块已经是被引进来了
4.3、编写接口测试
package top.noox.controller;
import top.noox.HelloService;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Resource
private HelloService helloService;
@GetMapping("/hello")
public String hello() {
return helloService.sayHello("tom");
}
}
YML配置
noox:
hello:
prefix: ppp
suffix: sss
server:
port: 80
4.4、访问
打开浏览器或者测试工具测试:localhost/hello
测试成功!