自定义xxx-spring-boot-starter
自定义xxx-spring-boot-starter
- 概要
- 1. 了解spring-boot-starter的核心注解
- 1.1 @EnableAutoConfiguration
- 1.2 @Import
- 2.以mybatis-plus-boot-starter为例理解自定义starter
- 2.1 创建配置类
- 2.2 创建imports文件
- 2.3 创建starter
- 3. 手写一个自定义starter
- 3.1 创建autoconfigure自动配置包
- 3.2 创建starter包
- 3.3 使用starter
概要
记录一个面试被问到的问题,springboot如何实现自动装配,使用springboot过程中,应该都使用过各种各样的spring-boot-starter,要如何自定义的starter,实现开箱即用?
要解答这个问题,需要了解几个Spring的注解:@EnableAutoConfiguration,@Import等。
1. 了解spring-boot-starter的核心注解
1.1 @EnableAutoConfiguration
我们知道springboot的核心注解@SpringBootApplication是一个组合注解,包含了
@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan。
- @SpringBootConfiguration表示标注的类是一个spring的配置类;
- @ComponentScan用于表示spring的包扫描路径 ,spring默认扫描路径为启动类所在包及其子包;
- @EnableAutoConfiguration也是一个组合注解,包含了@AutoConfigurationPackage和@Import注解。其中@Import标识了要自动注入的类名,如@SpringBootApplication下@EnableAutoConfiguration里的@Import(AutoConfigurationImportSelector.class)引入了AutoConfigurationImportSelector类。
1.2 @Import
@SpringBootApplication中@Import(AutoConfigurationImportSelector.class)生效过程:
- Spring应用在启动时会调用beanfactory后置处理器(见AbstractApplicationContext#refresh()中的
invokeBeanFactoryPostProcessors(beanFactory);)
@Overridepublic void refresh() throws BeansException, IllegalStateException {//... 省略部分代码 ...// Invoke factory processors registered as beans in the context.// 调用bean工厂后置处理器invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);beanPostProcess.end();//... 省略部分代码 ...}
- 在beanfactory后置处理器ConfigurationClassPostProcessor处理过程中会调用配置类解析器(ConfigurationClassParser)中的
parse(Set<BeanDefinitionHolder> configCandidates)方法去解析@Import中的属性值拿到@Import引入的类AutoConfigurationImportSelector
/*** Build and validate a configuration model based on the registry of* {@link Configuration} classes.*/public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {//... 省略部分代码 ...StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");// ConfigurationClassParser解析@Import注解parser