文章目录
前言
参考书籍《SpringBoot编程思想》— 小马哥mercyblitz
此书是难得的讲述SpringBoot的一本好书,由Spring的注解发展史介绍到Spring的注解驱动,以一个合适的切入点展开对SpringBoot注解驱动的加载和SpringApplication的启动过程的讨论。
建议有Spring基础再去看此书,收益颇丰。
本篇文章是上一篇文章 SpringBoot自动装配魔法之源码解析 的番外篇,主要的议题有下面两点:
- 示范一个专业的自动装配starter应该是怎样的,以及如何进行自定义的自动装配
- @ConditionalOnBean注解失效问题
自动装配规则
类命名规则
从spring.factories文件中,以EnableAutoConfiguration为key来搜索
可以发现一个规律,其自动装配的Bean的名称都是以AutoConfiguration结尾的,所以这里我们可以知道,类名需要以AutoConfiguration结尾。
package命名规则
还是以上述的类作为例子,我们随机截取三个类的包名作为示范:
- org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
- org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration
- org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration
可以发现,他们都是以org.springframework.boot.autoconfigure为开头的,org.springframework.boot说明这些都是官方的自动装配,而autoconfigure包说明用来存放自动装配类的。
从这里我们可以发现,命名的规则就是
${com.xxx.xxx}.autoconfigure.${功能模块名,如aop}.*AutoConfiguration
jar包构建规则
jar包结构
在官方文档中建议分为两个jar包,一个autoconfigure包,存放自动装配类和spring.factories,一个starter包,用来maven依赖刚刚的autoconfigure。就像下面这样
而starter单独一个jar包,依赖于上面的包。
在官方文档中说到,建议这样做,但如果需要简单的话,合并成一个jar包也是可以的。
jar包取名
接下来就是给jar包取名字了,在官方文档中,推荐开发人员使用如下命名
${module}-spring-boot-starter
此模式属于“第三方自定义starter”,而官方stater是什么样子呢?
spring-boot-starter-${module}
区别就在模块名在前在后,starter在前则表示此starter为官方定义的。从上面图片也可以看出这一点。
构建自定义的自动装配
接下来就开始自定义一个自动装配jar了。首先构建一个工程,其工程名为
<artifactId>stringbean-spring-boot-starter</artifactId>
然后创建一个合适的包名
构建一个自动装配的配置类
@Configuration
public class StringBeanAutoConfiguration {
@Bean
public String stringBean(){
return "world,hello";
}
}
将以上配置类放入META-INF下的spring.factories文件中去
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.microservice.original.autoconfigure.springbean.StringBeanAutoConfiguration
这样一个stater就做好了。然后将其jar依赖添加到另一个工程的pom文件中去
<dependency>
<groupId>com.microservice.original</groupId>
<artifactId>stringbean-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
测试的工程基本没东西
编写引导类
@EnableAutoConfiguration
public class TestAutoConfigure {
public static void main(String[] args) {
ConfigurableApplicationContext context = new SpringApplicationBuilder(TestAutoConfigure.class)
// 非WEB
.web