赞
踩
早在大学阶段就开始使用CSDN了,搜搜bug,找找项目。
但真正开始创作,开始分享自己的经验和心得还是在今年的2月份。初衷其实就是想记录一下备考计算机三级的笔记,虽然最终因为找工作等各种事宜没有考,但好在写文章、分享经验的习惯保留了下来,直到现在。
其实说实话,写作对我来说不是难事,而且我也喜欢写作,喜欢记录。大学期间就在学校的新媒体中心写公众号,自己也会偶尔发一下对生活对事情的感悟。开始在CSDN分享技术知识点、项目笔记后,我也学到了很多新知识,也逐渐对技术交流感兴趣。
对我来说,最大的收获就是自己在整理创作这些文章的时候所学到的内容。不仅仅是对技术性知识的掌握,同时还有写作思路的开阔,让自己能够在掌握知识的同时,也能将所学所悟分享给外界,从而进一步查缺补漏。
目前已经有373名粉丝,虽然大家可能都是无意间看到了我写的某篇文章,但只要能起到一点点帮助作用,就足够了。
就目前来说,创作已经融入进我的生活当中。在学习过程中遇到的有意思的问题,或者开发某个项目的流程,都会进行分享。
虽然这会加大工作量,因为全文都是我自己一个字一个字敲出来的,但在这个过程中也能重新梳理一遍知识,相当于重温一遍,加深记忆。
截止到目前的话,我认为就是现在正在做的从0开始的RPC框架项目。
- import cn.hutool.core.io.resource.ResourceUtil;
- import com.khr.krpc.serializer.Serializer;
- import lombok.extern.slf4j.Slf4j;
-
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.URL;
- import java.util.HashMap;
- import java.util.Arrays;
- import java.util.List;
- import java.util.Map;
- import java.util.concurrent.ConcurrentHashMap;
-
- /**
- * SPI加载器
- * 自定义实现,支持键值对映射
- */
- @Slf4j
- public class SpiLoader {
-
- /**
- * 存储已加载的类:接口名 =>(key => 实现类)
- */
- private static final Map<String, Map<String,Class<?>>> loaderMap = new ConcurrentHashMap<>();
-
- /**
- * 对象实例缓存(避免重复 new),类路径 => 对象实例,单例模式
- */
- private static final Map<String, Object> instanceCache = new ConcurrentHashMap<>();
-
- /**
- * 系统SPI目录
- */
- private static final String RPC_SYSTEM_SPI_DIR = "META-INF/rpc/system/";
-
- /**
- * 用户自定义SPI目录
- */
- private static final String RPC_CUSTOM_SPI_DIR = "META-INF/rpc/custom/";
-
- /**
- * 扫描路径
- */
- private static final String[] SCAN_DIRS = new String[]{RPC_SYSTEM_SPI_DIR,RPC_CUSTOM_SPI_DIR};
-
- /**
- * 动态加载的类列表
- */
- private static final List<Class<?>> LOAD_CLASS_LIST = Arrays.asList(Serializer.class);
-
- /**
- * 加载所有类型
- */
- public static void loadALl(){
- log.info("加载所有 SPI");
- for (Class<?> aClass : LOAD_CLASS_LIST){
- load(aClass);
- }
- }
-
- /**
- * 获取某个接口的实例
- *
- * @param tClass
- * @param key
- * @param <T>
- * @return
- */
- public static <T> T getInstance(Class<?> tClass,String key){
- String tClassName = tClass.getName();
- Map<String,Class<?>> keyClassMap = loaderMap.get(tClassName);
- if (keyClassMap == null){
- throw new RuntimeException(String.format("SpiLoader 未加载 %s 类型",tClassName));
- }
- if (!keyClassMap.containsKey(key)){
- throw new RuntimeException(String.format("SpiLoader 的 %s 不存在 key=%s 的类型", tClassName, key));
- }
- //获取到要加载的实现类型
- Class<?> implClass = keyClassMap.get(key);
- //从实例缓存中加载指定类型的实例
- String implClassName = implClass.getName();
- if (!instanceCache.containsKey(implClassName)){
- try {
- instanceCache.put(implClassName, implClass.newInstance());
- } catch (InstantiationException | IllegalAccessException e){
- String errorMsg = String.format("%s 类实例化失败",implClassName);
- throw new RuntimeException(errorMsg, e);
- }
- }
- return (T) instanceCache.get(implClassName);
- }
-
- /**
- * 加载某个类型
- *
- * @param loadClass
- * @throws IOException
- */
- public static Map<String, Class<?>> load(Class<?> loadClass){
- log.info("加载类型为 {} 的SPI",loadClass.getName());
- //扫描路径,用户自定义的SPI优先级高于系统SPI
- Map<String, Class<?>> keyClassMap = new HashMap<>();
- for (String scanDir : SCAN_DIRS){
- List<URL> resources = ResourceUtil.getResources(scanDir + loadClass.getName());
- //读取每个资源文件
- for (URL resource : resources){
- try {
- InputStreamReader inputStreamReader = new InputStreamReader(resource.openStream());
- BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
- String line;
- while ((line = bufferedReader.readLine()) != null){
- String[] strArray = line.split("=");
- if (strArray.length > 1){
- String key = strArray[0];
- String className = strArray[1];
- keyClassMap.put(key, Class.forName(className));
- }
- }
- } catch (Exception e){
- log.error("spi resource load error", e);
- }
- }
- }
- loaderMap.put(loadClass.getName(),keyClassMap);
- return keyClassMap;
- }
-
- public static void main(String[] args) throws IOException,ClassNotFoundException{
- loadALl();
- System.out.println(loaderMap);
- Serializer serializer = getInstance(Serializer.class, "json");
- System.out.println(serializer);
- }
- }
就在刚刚,我完成了项目中的SpiLoader加载器,相当于一个工具类,读取配置并加载实现类。
实不相瞒,创作这些文章的另一个目的就是为了找工作吧。春招失利了,虽然很沮丧很emo,但也没办法,只能说自己实力不够,距离自己想去的地方想做的工作还有差距,继续加油吧,多分享多创作,希望能有个好结果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。