自定义SpringBoot Starter实战
直接干,我们先来自己制作一个SpringBoot Starter,拿又拍云的SDK来玩玩
创建一个Maven项目
这个不说了,创建完是这样一个结构
配置Pom.xml文件
<properties>
<spring-boot.version>2.0.0.RELEASE</spring-boot.version>
<upyun-sdk.version>3.16</upyun-sdk.version>
</properties>
<dependencies>
<!-- Spring Boot dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<optional>true</optional>
<version>${spring-boot.version}</version>
</dependency>
<!-- @ConfigurationProperties annotation processing (metadata for IDEs) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
<version>${spring-boot.version}</version>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<version>${spring-boot.version}</version>
</dependency>
<!--upyun sdk-->
<dependency>
<groupId>com.upyun</groupId>
<artifactId>java-sdk</artifactId>
<version>${upyun-sdk.version}</version>
</dependency>
</dependencies>
① spring-boot-configuration-processor 包的作用是编译时生成 spring-configuration-metadata.json ,此文件主要给IDE使用。如当配置此jar相关配置属性在 application.yml ,你可以用ctlr+鼠标左键点击属性名,IDE会跳转到你配置此属性的类中。
② spring-boot-autoconfigure 包包括了@ConditionalOn开头的各种注解,并且内置了一些组件的自动换配置,如freemarker,kafka等
新建Properties文件
/**
* upyun 配置文件
*/
@ConfigurationProperties(prefix = "upyun")
public class UpyunProperties {
/**
* 服务名称
*/
private String bucketName;
/**
* 操作员账号
*/
private String operId;
/**
* 操作员密码
*/
private String operPass;
//....省略get,set
}
新建AutoConfiguration文件
/**
* Upyun Auto
*/
@Configuration
@ConditionalOnClass(UpYun.class)
@EnableConfigurationProperties(UpyunProperties.class)
public class UpyunAutoConfiguration {
@Resource
private UpyunProperties upyunProperties;
@Bean
@ConditionalOnMissingBean
public UpYun upYunAutoConfig(){
return new UpYun(upyunProperties.getBucketName(),upyunProperties.getOperId(),upyunProperties.getOperPass());
}
}
@ConditionalOnClass 表示当前路径下存在指定的类,才会创建该Bean @EnableConfigurationProperties:这个注解可以提供一种方便的方式来将带有 @ConfigurationProperties 注解的类注入为 Spring 容器的 Bean。 @ConditionalOnMissingBean:当 Spring Context中不存在该Bean时,才创建Bean
创建spring.factories文件
创建resources/META-INF/spring.factories文件,Springboot将从该文件读取自动配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.upyun.autoconfigure.UpyunAutoConfiguration
mvn clean install 本地打包安装 试一下
通过@Autowired 就可以引入Upyun对象
原理分析
实践完,我们来看看SpringBoot是如何加载自己的starter的
从SpringBoot Application的 run()进入源码,省略前面几个run代码,下面是主要方法
public ConfigurableApplicationContext run(String... args) {
...
//进入getRunListeners()方法
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
...
listeners.running(context);
return context;
}
在这里看到了一个getSpringFactoriesInstances()方法,看名字不就是spring.factories吗,我们在深入
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
SpringApplicationRunListener.class, types, this, args));
}
这里我们继续深入SpringFactoriesLoader.loadFactoryNames()方法
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<>(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
这么深入了,还没到,继续深入loadSpringFactories
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
终于到了加载spring.factories的地方了,这里会先判断内存中是否已经存在,不存在在从META-INF/spring.factories 加载,知道路径后,SpringBoot就知道已经加载哪些类了
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = cache.get(classLoader);
if (result != null)
return result;
try {
Enumeration<URL> urls = (classLoader != null ?
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
result = new LinkedMultiValueMap<>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry<?, ?> entry : properties.entrySet()) {
List<String> factoryClassNames = Arrays.asList(
StringUtils.commaDelimitedListToStringArray((String) entry.getValue()));
result.addAll((String) entry.getKey(), factoryClassNames);
}
}
cache.put(classLoader, result);
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load factories from location [" +
FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}
之前我们在spring.factories中已经有配置,SpringBoot就会根据配置加载我们的自定义starter了
到此,自己制作starter就实践完了,不知道你理解了没有,欢迎留言交流。
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
RxJS 实现摩斯密码(Morse) 【内附脑图】
参加 2018 ngChina 开发者大会,特别喜欢 Michael Hladky 奥地利帅哥的 RxJS 分享,现在拿出来好好学习工作坊的内容(工作坊Demo地址),结合这个示例,做了一个改进版本,实现更简洁,逻辑更直观。 一、摩斯密码是什么? 了解者可跳过次章节 摩斯密码(Morse),是一种时通时断的信号代码,这种信号代码通过不同的排列组合来表达不同的英文字母、数字和标点符号等。 地球人都知道的 SOS 求救信号,就是 Morse,三短(S) 三长(O) 三短(S)。 信号对应表如下: 二、业务逻辑分析 分析关键步骤,很巧,和把大象装进冰箱里同样都只需要三步耶: 第一步,识别点信号,短为 “滴” 长为“嗒”。 第二步,根据 “长间隔” 来切片分组。 第三步,分组数据根据对应表转化出最终结果。 三、撸代码,优化后版本(完整在线示例) 开始前要做好热身活动: Morse 的最小单元,"." 代表嘀,"-" 代表嗒,点击事件用 Down 代表 mousedown,Up 代表 mouseup。 200ms 间隔用来区别嘀嗒,1s 间隔用来区分一个 Morse 单元组的结束。 // 点信号...
-
下一篇
QQ音乐的动效歌词是如何实践的?
本文由云+社区发表 作者:QQ音乐技术团队 一、 背景 1. 现状 歌词浏览已经成为音乐app的标配,展示和动画效果也基本上大同小异,主要是单行的逐字染色的卡拉OK效果和多行的滚动效果。当然,我们也不例外。 2. 目标 我们的目标十分明确,一是提升歌词的基础体验,二是在此基础上,能提供差异化的VIP特效,来吸引用户开通VIP。 二、探索技术方案 经过多次的需求评审和沟通讨论,各方在需求的目标和细节上也达成了初步的统一。 产品的希望 :效果炫酷,能实现逐字动画(位移,翻转,渐隐渐现,模糊,粒子特效等),可配置等。开发的思考: 技术架构方案,性能挑战等,接下来我们简单介绍一下确定技术方案的过程。 1. 技术方案选型 这里最初的思路有两个方向,升级现有歌词组件和开发全新歌词组件。所谓知已知彼,百战不殆, 通过对移动端面主流竞品的技术方案和PC端类似方案的技术调研与分析。最终将技术方案锁定在以下三种: 现有歌词组件升级 Shader序列帧动画 ASS序列帧动画 2. 备选技术方案介绍 下面简单介绍一下三种方案的原理和特点,如下表所示: 总的来说,就是在原生动画开发和帧动画方案中进行选择。 3....
相关文章
文章评论
共有0条评论来说两句吧...



微信收款码
支付宝收款码