Spring boot一大特色就是提供了许多启动器,比如spring-boot-starter-webspring-boot-starter-cache等,这些启动器实现了自动配置,方便用户更快的聚焦于实际业务。对于我们来说,这也提供了一个新的思路去实现组件化:将过往的jar包封装提供类/方法依赖的模式改进成bean注入的模式。而这是通过我们可以开发自己的启动器去实现的。下面就说说如何去做。

创建工程

starter工程可以不是spring boot,只需要是一个maven工程即可。此时,我们需要在pom中指明依赖管理器。当然,如果你用spring boot去构建starter工程就不需要再声明这点。

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

这允许我们使用我们想要的任何Spring依赖,而无需导入整个启动器/ BOM并且不必自己提供版本号。

下一步是添加两个依赖项:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

第一个依赖项允许我们使用自动配置相关注解,而第二个依赖项允许我们为配置属性生成适当的元数据。

需要额外说明的是spring boot团队建议第三方的starter工程的artifactId命名为xxx-spring-boot-starter。我们遵循这个规范。

属性映射类

starter一般没有自己的属性文件,而是引用宿主的属性,比如在application.properties中配置的属性。下面是一个属性文件的示例:

adminapi.rolename=admin
adminapi.interval=6000

我们在starter中通过@ConfigurationProperties注解去获取属性值,代码示例;

@ConfigurationProperties("adminapi")
public class AdminapiProperties {
private String rolename = "admin";
private int interval = 10;
// Getters + Setters ...
}

@ConfigurationProperties表明这个POJO将用于绑定前缀为 adminapi 的所有配置属性。另一方面,属性名称应与POJO中的名称相同。所以在这种情况下,adminapi.rolename将匹配类中的rolename属性。

自动配置类

starter的核心就是这个自动配置类。下面是一个自动配置类的示例:

@Configuration
@ConditionalOnClass({AuthApi.class,DictApi.class,MenuApi.class,RoleApi.class,SystemApi.class,UserApi.class})
@AutoConfigureAfter(ServiceAutoConfigure.class)
@ConditionalOnWebApplication
@EnableConfigurationProperties(AdminapiProperties.class)
public class ApiAutoConfigure {
@Bean
@ConditionalOnMissingBean
public AuthApi authApi(AdminapiProperties adminProperties){
return new AuthApi(adminProperties.getRoleName());
}
}

首先要创建一个简单的类并使用注释对其进行@Configuration注释 。
之后,您必须通过添加@EnableConfigurationProperties注释来启用先前创建的配置属性。
您还可以自定义Spring何时调用自动配置。在我们的例子中,由于我们是Api层,我们希望在加载Service层之后再配置(否则会找不到bean)。为此,我们可以使用@AutoConfigureAfter注释。

ConditionOn是条件语句,在例子中,我们要求确保这些class都存在,才去执行自动配置,所以我们使用了ConditionOnClassConditionOnWebApplication是要求仅当是web项目时才进行自动配置。像这样的注解还有一些,你可以在IDEA中通过自动提示去查看,一般看名字大概就知道含义了。

在完成上述工作之后,就可以在里面愉快的注册bean了。

编写Spring Factories

在将Spring启动启动器包含在其他项目中之前,您还需要做一件事。为了使应用程序获得我们的Spring启动启动器,我们必须创建一个名为spring.factories的特殊属性文件。此文件应放在src / main / resources / META-INF文件夹中,并应包含该org.springframework.boot.autoconfigure.EnableAutoConfiguration属性,例如:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.winning.adminapi.configure.LogAspectAutoConfigure,\
com.winning.adminapi.configure.ApiAutoConfigure,\
com.winning.adminapi.configure.SecurityAutoConfigure,\
com.winning.adminapi.configure.ServiceAutoConfigure,\
com.winning.adminapi.configure.UtilAutoConfigure,\
com.winning.adminapi.configure.SwaggerAutoConfigure,\
com.winning.adminapi.configure.ApiInitAutoConfigure

此属性应包含autoconfiguration类的完整路径。

如何发布

starter项目的发布和普通项目没有什么区别,比如通过maven deploy发布到maven私仓。

如何使用

其他项目需要使用该starter项目时,只需要在pom中导入。启动工程后,spring boot会将自动配置类中指明的bean装载到bean factory中,像使用本地bean的方式去使用它。

END

欢迎留言讨论。这是一个可参考的源码