当前位置:   article > 正文

活动:我的创作纪念日

活动:我的创作纪念日

机缘

早在大学阶段就开始使用CSDN了,搜搜bug,找找项目。

但真正开始创作,开始分享自己的经验和心得还是在今年的2月份。初衷其实就是想记录一下备考计算机三级的笔记,虽然最终因为找工作等各种事宜没有考,但好在写文章、分享经验的习惯保留了下来,直到现在。

其实说实话,写作对我来说不是难事,而且我也喜欢写作,喜欢记录。大学期间就在学校的新媒体中心写公众号,自己也会偶尔发一下对生活对事情的感悟。开始在CSDN分享技术知识点、项目笔记后,我也学到了很多新知识,也逐渐对技术交流感兴趣。


收获

对我来说,最大的收获就是自己在整理创作这些文章的时候所学到的内容。不仅仅是对技术性知识的掌握,同时还有写作思路的开阔,让自己能够在掌握知识的同时,也能将所学所悟分享给外界,从而进一步查缺补漏。

目前已经有373名粉丝,虽然大家可能都是无意间看到了我写的某篇文章,但只要能起到一点点帮助作用,就足够了。


日常

就目前来说,创作已经融入进我的生活当中。在学习过程中遇到的有意思的问题,或者开发某个项目的流程,都会进行分享。

虽然这会加大工作量,因为全文都是我自己一个字一个字敲出来的,但在这个过程中也能重新梳理一遍知识,相当于重温一遍,加深记忆。


成就

截止到目前的话,我认为就是现在正在做的从0开始的RPC框架项目。

  1. import cn.hutool.core.io.resource.ResourceUtil;
  2. import com.khr.krpc.serializer.Serializer;
  3. import lombok.extern.slf4j.Slf4j;
  4. import java.io.BufferedReader;
  5. import java.io.IOException;
  6. import java.io.InputStreamReader;
  7. import java.net.URL;
  8. import java.util.HashMap;
  9. import java.util.Arrays;
  10. import java.util.List;
  11. import java.util.Map;
  12. import java.util.concurrent.ConcurrentHashMap;
  13. /**
  14. * SPI加载器
  15. * 自定义实现,支持键值对映射
  16. */
  17. @Slf4j
  18. public class SpiLoader {
  19. /**
  20. * 存储已加载的类:接口名 =>(key => 实现类)
  21. */
  22. private static final Map<String, Map<String,Class<?>>> loaderMap = new ConcurrentHashMap<>();
  23. /**
  24. * 对象实例缓存(避免重复 new),类路径 => 对象实例,单例模式
  25. */
  26. private static final Map<String, Object> instanceCache = new ConcurrentHashMap<>();
  27. /**
  28. * 系统SPI目录
  29. */
  30. private static final String RPC_SYSTEM_SPI_DIR = "META-INF/rpc/system/";
  31. /**
  32. * 用户自定义SPI目录
  33. */
  34. private static final String RPC_CUSTOM_SPI_DIR = "META-INF/rpc/custom/";
  35. /**
  36. * 扫描路径
  37. */
  38. private static final String[] SCAN_DIRS = new String[]{RPC_SYSTEM_SPI_DIR,RPC_CUSTOM_SPI_DIR};
  39. /**
  40. * 动态加载的类列表
  41. */
  42. private static final List<Class<?>> LOAD_CLASS_LIST = Arrays.asList(Serializer.class);
  43. /**
  44. * 加载所有类型
  45. */
  46. public static void loadALl(){
  47. log.info("加载所有 SPI");
  48. for (Class<?> aClass : LOAD_CLASS_LIST){
  49. load(aClass);
  50. }
  51. }
  52. /**
  53. * 获取某个接口的实例
  54. *
  55. * @param tClass
  56. * @param key
  57. * @param <T>
  58. * @return
  59. */
  60. public static <T> T getInstance(Class<?> tClass,String key){
  61. String tClassName = tClass.getName();
  62. Map<String,Class<?>> keyClassMap = loaderMap.get(tClassName);
  63. if (keyClassMap == null){
  64. throw new RuntimeException(String.format("SpiLoader 未加载 %s 类型",tClassName));
  65. }
  66. if (!keyClassMap.containsKey(key)){
  67. throw new RuntimeException(String.format("SpiLoader 的 %s 不存在 key=%s 的类型", tClassName, key));
  68. }
  69. //获取到要加载的实现类型
  70. Class<?> implClass = keyClassMap.get(key);
  71. //从实例缓存中加载指定类型的实例
  72. String implClassName = implClass.getName();
  73. if (!instanceCache.containsKey(implClassName)){
  74. try {
  75. instanceCache.put(implClassName, implClass.newInstance());
  76. } catch (InstantiationException | IllegalAccessException e){
  77. String errorMsg = String.format("%s 类实例化失败",implClassName);
  78. throw new RuntimeException(errorMsg, e);
  79. }
  80. }
  81. return (T) instanceCache.get(implClassName);
  82. }
  83. /**
  84. * 加载某个类型
  85. *
  86. * @param loadClass
  87. * @throws IOException
  88. */
  89. public static Map<String, Class<?>> load(Class<?> loadClass){
  90. log.info("加载类型为 {} 的SPI",loadClass.getName());
  91. //扫描路径,用户自定义的SPI优先级高于系统SPI
  92. Map<String, Class<?>> keyClassMap = new HashMap<>();
  93. for (String scanDir : SCAN_DIRS){
  94. List<URL> resources = ResourceUtil.getResources(scanDir + loadClass.getName());
  95. //读取每个资源文件
  96. for (URL resource : resources){
  97. try {
  98. InputStreamReader inputStreamReader = new InputStreamReader(resource.openStream());
  99. BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
  100. String line;
  101. while ((line = bufferedReader.readLine()) != null){
  102. String[] strArray = line.split("=");
  103. if (strArray.length > 1){
  104. String key = strArray[0];
  105. String className = strArray[1];
  106. keyClassMap.put(key, Class.forName(className));
  107. }
  108. }
  109. } catch (Exception e){
  110. log.error("spi resource load error", e);
  111. }
  112. }
  113. }
  114. loaderMap.put(loadClass.getName(),keyClassMap);
  115. return keyClassMap;
  116. }
  117. public static void main(String[] args) throws IOException,ClassNotFoundException{
  118. loadALl();
  119. System.out.println(loaderMap);
  120. Serializer serializer = getInstance(Serializer.class, "json");
  121. System.out.println(serializer);
  122. }
  123. }

就在刚刚,我完成了项目中的SpiLoader加载器,相当于一个工具类,读取配置并加载实现类。 


憧憬

实不相瞒,创作这些文章的另一个目的就是为了找工作吧。春招失利了,虽然很沮丧很emo,但也没办法,只能说自己实力不够,距离自己想去的地方想做的工作还有差距,继续加油吧,多分享多创作,希望能有个好结果。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/951007
推荐阅读
相关标签
  

闽ICP备14008679号