自定义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条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- Red5直播服务器,属于Java语言的直播服务器
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Hadoop3单机部署,实现最简伪集群
- CentOS8编译安装MySQL8.0.19