-
Starter原理剖析; -
自定义一个Starter并使用
Starter的命名也有讲究,官方的Starter以这样的模式命令:spring-boot-starter-*,*代表应用的特定类型,比如下面这样的:
spring-boot-starter-web
spring-boot-starter-activemq
spring-boot-starter-data-mongodb
spring-boot-starter-batch
而第三方Starter,比如自定义的Starter,一般是以模块的名字开头,再加上spring-boot-starter,这样的话方便区分,比如:
acme-spring-boot-starter
fslog-spring-boot-starter
二、Starter的工作原理
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
在IDEA中,使用Ctrl+鼠标左键,可以看到它依赖的底层源文件:
在Spring Boot的启动类中,会加上注解@SpringBootApplication,查看这个注解的详情,会发现它由以下注解组成(主要部分):
EnableAutoConfiguration:这个注解借用@Import,注册依赖包中的相关Bean;
在自动配置的功能实现中,这个注解非常关键EnableAutoConfiguration,它会@Import(AutoConfigurationImportSelector.class),而这个类中的方法selectImports最终会从META-INF/spring.factories文件中加载EnableAutoConfiguration里面的配置值
三、自定义Starter
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.fullstack</groupId>
<artifactId>fs-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>mystarter-spring-boot-starter</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
</project>
package com.fullstack.commerce.message;
public interface PrintService {
String print(String msg);
}
package com.fullstack.commerce.message.impl;
import com.fullstack.commerce.message.PrintService;
public class PrintServiceImpl implements PrintService {
@Override
public String print(String msg) {
return "Starter print:"+msg;
}
}
然后是自动配置类,它是Starter的关键部分,把业务相关的Bean加载进来:
package com.fullstack.commerce.config;
import com.fullstack.commerce.message.PrintService;
import com.fullstack.commerce.message.impl.PrintServiceImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(PrintProperties.class) // 它使注解@ConfigurationProperties生效
@ConditionalOnClass(value = {PrintService.class, PrintServiceImpl.class}) // 只有业务类位于classpath上,才会实例当前这个配置类
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean //只有当前上下文不存在这个bean时,才会实例化
PrintService printService(){
return new PrintServiceImpl();
}
}
package com.fullstack.commerce.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "com.fullstack")
public class PrintProperties {
private String defaultMsg="Starter msg";
public String getDefaultMsg() {
return defaultMsg;
}
public void setDefaultMsg(String defaultMsg) {
this.defaultMsg = defaultMsg;
}
}
还需要在目录resources/META-INF下创建文件:spring.factories,这个文件把AutoConfiguration配置进去:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
com.fullstack.commerce.config.MyAutoConfiguration
<dependency>
<groupId>com.fullstack</groupId>
<artifactId>mystarter-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
@Resource
private PrintService printService;
@Resource
private PrintProperties printProperties;
@RequestMapping("/print")
public String print(@RequestParam String msg){
return printService.print(msg+",配置的消息为:"+printProperties.getDefaultMsg());
}
com.fullstack.defaultMsg=customized msg
再运行上面的程序,则显示配置后的文字:
推荐阅读:
原文始发于微信公众号(互联网全栈架构):Spring Boot Starter原理及实践
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/173535.html