您的位置:首页 > 健康 > 养生 > 湖南网站seo地址_王通seo_唐山seo优化_seo的研究对象

湖南网站seo地址_王通seo_唐山seo优化_seo的研究对象

2025/3/13 5:13:52 来源:https://blog.csdn.net/gdr12/article/details/146133220  浏览:    关键词:湖南网站seo地址_王通seo_唐山seo优化_seo的研究对象
湖南网站seo地址_王通seo_唐山seo优化_seo的研究对象

利用FatJar彻底解决Jar包冲突

  • 出⼊参的拷⻉
    • 背景
    • 现有技术调研与对⽐
    • 代码实现
  • ⽇志-logback
    • 配置⽂件
    • ⽇志依赖
  • autoconfig 注⼊ FatJar
    • 被注⼊⽂件的位置
    • 注⼊ Jar in FatJar

出⼊参的拷⻉

背景

在依赖隔离的情况下,由于⼆⽅包是通过不同ClassLoader加载的,所以要调⽤⼆⽅包⾥的⽅法需要利⽤反射。然⽽在利⽤ 反射调⽤时传⼊的参数实例的ClassLoader是通过AppClassLoader加载的,⽽接收这个参数的类是⽤FatJarClassLoader加载 的,同类名不同ClassLoader加载是不同的类,返回值也是⼀样,所以需要在出⼊参时对Object进⾏转换:

Map targetMap = copyMap(var2); 
fromObject = this.executeMethod.invoke(this.bizService,var1,targetMap); 
BusinessServiceResultDTO result = (BusinessServiceResultDTO) convert(fromObject,BusinessServiceResultDTO.class);

现有技术调研与对⽐

调研的技术主要有两个:

  1. 使⽤Spring的BeanUtils,这种⽅式只⽀持⼀层拷⻉,即当复杂类对象⾥不包含其他复杂类属 性时是可以的,但是如果包含就不会转换属性Object;
  2. 使⽤Jackson 的ObjectMapper,这种⽅式通过先将Java Object 转成Json格式再从Json格式创建另⼀个classloader加载的类实例,显然这种⽅式的效率会很低,为了确保服务调⽤的响应速度,也考虑到⾃⼰实现的代价不⼤,因为两个类的字段完全⼀样只是通过不同classloader加载的。

代码实现

public static Object convert(Object fromObject,Class toClass){ if (fromObject == null ||fromObject.getClass() == toClass || toClass.isAssignableFrom(fromObject.getClass)) return fromObject; }Object toObject = null; try {toObject = toClass.newInstance(); } catch (Exception e) { logger.error("new instance error:"+toClass.getSimpleName(),e); }Class fromClass = fromObject.getClass(); Field[] fields = fromClass.getDeclaredFields(); for (Field fromField:fields) { try{fromField.setAccessible(true); Object fromVal = fromField.get(fromObject); if (fromVal == null){ continue; }String fieldName = fromField.getName();if("serialVersionUID".equals(fieldName)){ continue;}Field toField = toClass.getDeclaredField(fieldName); toField.setAccessible(true); Class fromFieldClass = fromVal.getClass(); Class toFieldClass = toField.getType(); if(fromFieldClass.getClassLoader() != null){ // 复杂对象toField.set(toObject,convert(fromVal,toFieldClass));}else{ClassLoader toClassLoader = toClass.getClassLoader(); if (List.class.isAssignableFrom(fromFieldClass)){ List fromList = (List)fromVal; List toList = (List)fromFieldClass.newInstance(); for (Object o : fromList) { if (o.getClass().getClassLoader() != null){ // 这边强制使⽤同类名转换 toList.add(convert(o,toClassLoader.loadClass(o.getClass().getName()))); }else{toList.add(o); } }toField.set(toObject,toList); }else if (Map.class.isAssignableFrom(fromFieldClass)){ Map fromMap = (Map)fromVal; Map toMap = (Map)fromFieldClass.newInstance(); for (Object fromKey:fromMap.keySet()) { Object fromValue = fromMap.get(fromKey); Object toKey = convert(fromKey,toClassLoader.loadClass(fromKey.getClass().getName()));Object toValue = convert(fromValue,toClassLoader.loadClass(fromValue.getClass().getName())); toMap.put(toKey,toValue); }toField.set(toObject,toMap); }else if (Set.class.isAssignableFrom(fromFieldClass)){ Set fromSet = (Set)fromVal; Set toSet = (Set)fromFieldClass.newInstance(); for (Object o : fromSet) { if (o.getClass().getClassLoader() != null){ // 这边强制使⽤同类名转换 toSet.add(convert(o,toClass.getClassLoader().loadClass(o.getClass().getName()))); }else{toSet.add(o); } }toField.set(toObject,toSet); }else{toField.set(toObject,fromVal); } } }catch (Exception e){ logger.error("convert error:",e); } }return toObject; 
}

⽇志-logback

由于完全隔离,⼆⽅包需要有⾃⼰的⽇志系统。这⼀节介绍⼆⽅包如何使⽤⾃⼰的⽇志系统。

配置⽂件

logback 查找配置⽂件的流程为:

  1. 在classpath下查找配置⽂件 logback-test.xml
  2. 如果⽂件不存在则查找 logback.xml 所以配置⽂件的位置为:
    在这里插入图片描述
    配置⽂件内容:
    在这里插入图片描述

⽇志依赖

根据⽇志依赖冲突:
在这里插入图片描述
为了让⼆⽅包⽀持logback⽇志,且⾃身内部不冲突,根据⽇志框架的结构图配置pom⽇志依赖如下,这些统⼀依赖都会写 到parent⾥让⼆⽅包的pom更简洁。
在这里插入图片描述

autoconfig 注⼊ FatJar

被注⼊⽂件的位置

由于autoconfig是在打完包之后执⾏的,因此在autoconfig配置⽂件中需要指定的注⼊⽂件的位置应该根据打包之后的⽬录 结构来配置:
在这里插入图片描述

注⼊ Jar in FatJar

如果还使⽤之前的autoconfig插件,autoconfig在注⼊jarin FatJar之后会对jar 进⾏压缩导致FatJarClassLoader在加载该jar包 的时候加载失败。通过咨询autoconfig的同学,发现autoconfig其实提供了注⼊FatJar的插件(pandora boot采⽤的这种⽅ 式),由此也可⻅之前选择这种格式FatJar的正确性。
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com