徒手擼了一個 starter,同事直誇我 666~
大家好,我是大堯!
Spring Boot starter 原理
Spring Boot 將常見的開發功能,分成了一個個的 starter,這樣我們開發功能的時候只需要引入對應的 starter,而不需要去引入一堆依賴了!starter 可以理解爲一個依賴組,其主要功能就是完成引入依賴和初始化配置。Spring 官方提供的 starter 命名規範爲 spring-boot-starter-xxx
,第三方提供的 starter 命名規範爲 xxx-spring-boot-starter
。
這裏我們以 RocketMQ
的依賴 rocketmq-spring-boot-starter
來學習 starter 的原理。
在項目中引入 rocketmq-spring-boot-starter
之後,實際上就引入了 rocketmq
的一些相關依賴。
在 rocketmq-spring-boot
中有一個自動裝配的類RocketMQAutoConfiguration
,我截取了其中的一小段代碼,一起來看看。
@Configuration
@EnableConfigurationProperties(RocketMQProperties.class)
@ConditionalOnClass({MQAdmin.class})
@ConditionalOnProperty(prefix = "rocketmq", value = "name-server", matchIfMissing = true)
@Import({MessageConverterConfiguration.class, ListenerContainerConfiguration.class, ExtProducerResetConfiguration.class, RocketMQTransactionConfiguration.class})
@AutoConfigureAfter({MessageConverterConfiguration.class})
@AutoConfigureBefore({RocketMQTransactionConfiguration.class})
public class RocketMQAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(RocketMQAutoConfiguration.class);
public static final String ROCKETMQ\_TEMPLATE\_DEFAULT\_GLOBAL\_NAME =
"rocketMQTemplate";
@Autowired
private Environment environment;
@Bean(destroyMethod = "destroy")
@ConditionalOnBean(DefaultMQProducer.class)
@ConditionalOnMissingBean(name = ROCKETMQ\_TEMPLATE\_DEFAULT\_GLOBAL\_NAME)
public RocketMQTemplate rocketMQTemplate(DefaultMQProducer mqProducer,
RocketMQMessageConverter rocketMQMessageConverter) {
RocketMQTemplate rocketMQTemplate = new RocketMQTemplate();
rocketMQTemplate.setProducer(mqProducer);
rocketMQTemplate.setMessageConverter(rocketMQMessageConverter.getMessageConverter());
return rocketMQTemplate;
}
}
-
@Configuration 說明這是一個配置類,類中被 @Bean 註解了的方法,就是 spring 的一個 bean,例如
rocketMQTemplate
。 -
@EnableConfigurationProperties,啓用被 @ConfigurationProperties 的 bean,這裏引入了
RocketMQProperties
。
RocketMQProperties
就是需要在 yml 文件中寫入的屬性。
@ConfigurationProperties(prefix = "rocketmq")
public class RocketMQProperties {
private String nameServer;
private String accessChannel;
private Producer producer;
private Consumer consumer = new Consumer();
}
在 Spring Boot 項目啓動的時候默認只會掃描下級目錄下帶 @Configuration
註解的類,那麼像本文中提到的 RocketMQAutoConfiguration
是如何掃描的呢?其實項目啓動的時候會去加載項目中所有的 spring.factories
文件,然後加載對應的配置類,因此我們就需要在 spring.factories
中只指定需要掃描的類。
原理搞明白了,接下來我們就簡單實現一個自己的 starter!這個 starter 的主要作用就是給一個對象尾部拼接一個字符串!
一、新建項目
新建一個名爲 javatip-spring-boot-starter
的項目,並且引入下面的依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
二、新增配置類
配置類對應的 properties 文件中的屬性爲javatip.name
;
@ConfigurationProperties(prefix = "javatip")
public class JavatipPorperties {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
三、新增拼接字符串的方法
此方法主要就是爲對象拼接一個固定的字符串
public class StrUt {
private String name;
public String strTo(Object object){
return object +"---"+ getName();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
四、新增自動配置類
使用註解 @EnableConfigurationProperties
啓用 JavatipProperties
配置類
使用註解 @Configuration
配合 @Bean
註冊一個拼接字符串的 bean 對象。
@Configuration
@EnableConfigurationProperties(JavatipPorperties.class)
public class JavatipAutoConfiguration {
@Autowired
private JavatipPorperties javatipPorperties;
@Bean
public StrUt strut(){
StrUt strut = new StrUt();
strut.setName(javatipPorperties.getName());
return strut;
}
}
五、新增配置發現文件
在 resources 文件夾中新建 META-INF
文件夾,在 META-INF
文件夾中新建配置發現文件 spring.factories
,並且將自動配置類寫到文件裏。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.javatip.str.configuration.JavatipAutoConfiguration
六、打包測試
使用 mvn install
命令將項目打包推送到本地 maven 倉庫,然後新建一個測試項目,引入打包好的依賴。
<dependency>
<groupId>com.javatip</groupId>
<artifactId>javatip-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
在 application.yml
文件中寫入自動拼接的字符串對應的屬性 javatip.name
。
javatip:
name: Java旅途
然後手寫一個測試類:
@RestController
public class Test {
@Autowired
private StrUt strUt;
@GetMapping("test")
public String test(){
String str = strUt.strTo("who are you?");
return str;
}
}
運行測試類後,頁面返回了
who are you?---Java旅途
這樣,一個簡單的 starter 就寫好了,只要理解了 starter 的原理,實現起來就很簡單,第一點就是 starter 相當於一個依賴組,另一點就是 starter 可以完成初始化配置。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。