为什么要用starter
1、封装通用的依赖包,便于引入
2、版本依赖的统一
通常一个项目会依赖多个依赖,在项目迭代过程中,假如版本存在冲突,还要去一个一个去排查依赖版本问题,有了Starter就统一当前项目版本的依赖,想要调用直接引入pom即可
编写starter步骤
1.需要定义一个名称为xxx-spring-boot-starter的空项目,里面不包含任何代码,可以有pom.xml和properties文件。
2.pom.xml文件中包含了名称为xxx-spring-boot-autoconfigure的项目。
3.xxx-spring-boot-autoconfigure项目中包含了名称为xxxAutoConfiguration的类,该类可以定义一些bean实例。当然,Configuration类上可以打一些如:ConditionalOnClass、ConditionalOnBean、EnableConfigurationProperties等注解。
4.需要在spring.factories文件中增加key为EnableAutoConfiguration,value为xxxAutoConfiguration。
自定义Starter案例
1、引入依赖
<!--添加 Starter 的自动化配置类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2、添加默认配置属性与配置类
@ConfigurationProperties(prefix = "link")
@Data
public class HelloProperties {
private static final String DEFAULT_NAME = "link";
private static final String DEFAULT_MSG = "hello";
private String name = DEFAULT_NAME;
private String msg = DEFAULT_MSG;
}
3、添加自动配置
- 引入业务类
@Data
public class HelloService {
private String msg;
private String name;
public void say() {
System.out.println(name + ":" + msg);
}
}
- 定义自动配置
@Configuration
@EnableConfigurationProperties(HelloProperties.class) // 让配置类生效
@ConditionalOnClass(HelloService.class) // 前置配置
public class HelloServiceAutoConfiguration {
@Autowired
HelloProperties helloProperties;
@Bean
HelloService helloService() {
HelloService helloService = new HelloService();
helloService.setName(helloProperties.getName());
helloService.setMsg(helloProperties.getMsg());
return helloService;
}
}
5、配置自动加载类路径
使用spring的SPI机制,配置属性org.springframework.boot.autoconfigure.EnableAutoConfiguration要自动扫描的类
6、在其他项目调用
<dependency>
<groupId>com.example</groupId>
<artifactId>spring-boot-starter-link</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
-
设置配置属性
-
测试自动配置starter
@SpringBootTest
class DemoApplicationTests {
@Autowired
HelloService helloService;
@Test
public void contextLoads() {
System.out.println(helloService.say());
}
}
原理
Application类的@SpringBootApplication注解
,该注解里面包含了@EnableAutoConfiguration注解,@EnableAutoConfiguration注解会引入AutoConfigurationImportSelector类。该类的selectImports方法一个关键方法:
//找spring-autoconfigure-metadata.properties中的元素
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
//获取EnableAutoConfiguration注解中的属性
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//获取工程下所有配置key为EnableAutoConfiguration的值,即HelloServiceAutoConfiguration 等类。
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
//删除重复的值
configurations = removeDuplicates(configurations);
//获取需要排除的规则列表
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
//检查
checkExcludedClasses(configurations, exclusions);
//删除需要排除的值
configurations.removeAll(exclusions);
//根据配置文件中配置的开关,过滤一部分不满足条件的值
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return StringUtils.toStringArray(configurations);