我们常常将一些通用的功能封装成Jar包,供不同的项目使用。同样在SpringBoot的开发中,也可以将一些通用的功能封装,根据SpringBoot的自动装配的约定,可以封装自己的starter,然后在Spring Boot环境中完成一些通用功能的注入。

原理

哪些Bean可以自动装配

首先,会寻找@Configuration注解标注的类,添加@Conditional条件注解约束什么时候可以被装配,通常会用@ConditionalOnClass@ConditionalOnMissingBean,相关的类能找到,并且没有声明的时候注入。

如何定位要装配的Bean

检查Jar包META-INF/spring.factories下的文件,是否有声明:

1
2
3
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration

常用的条件注解

Class Conditions

类条件注解:

  • @ConditionalOnClass,指定的类在类路径下生效;
  • @ConditionalOnMissingClass,指定的类不在类路径下生效。

Bean Conditions

Bean条件:

  • @ConditionalOnBean,当需要的Bean存在时,才生效;
  • @ConditionalOnMissingBean,当Bean不存在时生效。

Property Conditions

@ConditionalOnProperty基于Spring的环境属性配置包括在内。使用prefix和name属性来指定应检查的属性。默认情况下,匹配任何存在且不等于false的属性。您还可以使用havingValue和matchIfMissing属性创建更高级的检查。

Resource Conditions

@ConditionalOnResource允许仅在存在特定资源时才包含配置。可以使用常见的Spring约定来指定资源。比如:file:/home/user/test.dat

Web Application Conditions

@ConditionalOnWebApplication@ConditionalOnNotWebApplication注解在程序是否是一个web程序的时候生效。

创建自定义的starter

需求:开发一个starter,读取配置文件,并简单打印出来。

引入依赖

由于是自动装配,需要引入:

1
2
3
4
5
6
7
8
9
10
<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>
</dependency>
</dependencies>

将配置文件封装一个Bean

1
2
3
4
5
6
7
8
@ConfigurationProperties(prefix = "myself.author")
public class AuthorInfoBean {
private String name;
private String tel;
private String address;
private String sex;
// get set方法
}

对外暴露的接口

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

private AuthorInfoBean authorInfoBean;
// 构造函数,传入配置文件
public AuthorService(AuthorInfoBean authorInfoBean) {
this.authorInfoBean = authorInfoBean;
}

/** 对外提供的服务*/
public String printAuthor() {
System.out.println(authorInfoBean.toString());
return authorInfoBean.toString();
}
}

配置类

1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
@EnableConfigurationProperties(AuthorInfoBean.class)
@ConditionalOnClass(AuthorService.class)
@ConditionalOnProperty(prefix = "myself.author", value = "enabled", matchIfMissing = true)
public class SelfAutoConfig {

@Bean
@ConditionalOnMissingBean(AuthorService.class)
public AuthorService authorService (AuthorInfoBean authorInfoBean) {
return new AuthorService(authorInfoBean);
}
}

然后再resources/META-INF/spring.factories中添加:

1
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.abumaster.myself.config.SelfAutoConfig

打包,发布

1
2
3
mvn package
#先安装到本地
mvn install

使用

在需要用到的模块中引用:

1
2
3
4
5
<dependency>
<groupId>com.abumaster.myself</groupId>
<artifactId>myself-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>

配置文件中,可以使用定义的配置项:

1
2
3
4
5
myself:
author:
name: xxx
tel: xxx
address: 武汉

在Java代码中,注入直接使用:

1
2
@Autowired
private AuthorService authorService;