当前位置: 首页 > news >正文

springBoot动态加载jar,将类注册到IOC

具体实现

Service

public interface JarService {Boolean loadJarByName(LoadJarDTO dto);
}

impl:


@Service
@RequiredArgsConstructor
@Slf4j
public class JarServiceImpl implements JarService {private final SpringContextUtil springContextUtil;@Overridepublic Boolean loadJarByName(LoadJarDTO dto) {//初始化File-加载jar所在目录File jarFile = new File(dto.getJarPath());if (!jarFile.exists()){return false;}List<String> loadClassList = this.getLoadClass(jarFile.getAbsolutePath());if (CollectionUtils.isEmpty(loadClassList)){return false;}//加载jarClassLoader classLoader = ClassLoaderUtil.getJarClassLoader(jarFile);for (String loadClassPath : loadClassList) {Class<?> clazz = null;try {clazz = classLoader.loadClass(loadClassPath);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}if(!this.isLoadClass(clazz)){continue;}//生成需要注册到ioc的bean名称// clazz.getSimpleName()用于获取表示该类的简单名称(不包括包名)。简单名称就是类名本身,而不带任何修饰或包的前缀。String beanName = getBeanName(dto.getPreBeanName(),clazz.getSimpleName()) ;//加载需要加载的if (!dto.getIsOverLoad() && springContextUtil.containsBeanDefinition(beanName)){continue;}if (dto.getIsOverLoad() && springContextUtil.containsBeanDefinition(beanName)){springContextUtil.unregisterBean(beanName);}springContextUtil.registerBean(beanName,clazz);}return true;}private static String getBeanName(String name, String className) {return StringUtils.uncapitalize(name) + StringUtils.capitalize(className);}private boolean isLoadClass(Class<?> clazz) {if (clazz == null){return false;}//是否是接口if (clazz.isInterface()){return false;}//是否是抽象类if (Modifier.isAbstract(clazz.getModifiers())){return false;}if (clazz.getAnnotation(Service.class) != null){return true;}if (clazz.getAnnotation(Component.class) != null){return true;}if (clazz.getAnnotation(Repository.class) != null){return true;}if (clazz.getAnnotation(Configuration.class) != null){return true;}return false;}private List<String> getLoadClass(String jarPath) {Set<String> classPathList = new HashSet<>();File file = new File(jarPath);//获取jar的流,打开jar文件try ( JarInputStream jarInputStream = new JarInputStream(FileUtil.getInputStream(file))){//逐个获取jar种文件JarEntry jarEntry = jarInputStream.getNextJarEntry();//遍历while (jarEntry != null){//获取文件路径String name = jarEntry.getName();if (name.endsWith(".class")){String classNamePath = name.replace(".class", "").replace("/",".");classPathList.add(classNamePath);}jarEntry = jarInputStream.getNextJarEntry();}} catch (IOException e) {log.error(e.getMessage());throw new RuntimeException("获取加载类路径失败");}return new ArrayList<>(classPathList);}
}

使用:

新建一模块,写一个简单类:

@Service
public class CalculateServiceImpl implements CalculateService {@Overridepublic int add(int a, int b) {return a + b;}@Overridepublic int minus(int a, int b) {return a - b;}
}

建立一个公共接口,放在公共模块,以供加载jar时候,可以获取接口方法

public interface CalculateService {int add(int a,int b);int minus(int a ,int b);
}

然后 cleam-install打成jar

建立一加载使用:

    @GetMapping("/calculate/{beanName}/{a}/{b}")private Integer calculate( @PathVariable(value = "beanName") String beanName,@PathVariable(value = "a") Integer a, @PathVariable("b") Integer b){return jarService.calculate(beanName,a,b);}@Overridepublic Integer calculate(String beanName, Integer a, Integer b) {CalculateService calculateService = SpringContextUtil.getBean(getBeanName(beanName,beanName+"Impl"), CalculateService.class);int add = calculateService.add(a, b);return add;}private static String getBeanName(String name, String className) {return StringUtils.uncapitalize(name) + StringUtils.capitalize(className);}


http://www.mrgr.cn/news/64796.html

相关文章:

  • 【数据分析】怎么提升GMV
  • df_new_last.iloc[:,-1]与df_new_last.iloc[:,:-1]
  • Redis 的使⽤和原理
  • IT运维的365天--018 如何在内网布置一个和外网同域名的网站,并开启SSL(https访问),即外网证书如何在内网使用
  • Kubernetes中常见的volumes数据卷
  • SPI协议——笔记
  • cangjie仓颉程序设计-数据结构(四)
  • [LeetCode] 面试题08.01 三步问题
  • 企业实现数字化转型需要考虑的方面?
  • LeetCode题练习与总结:超级次方--372
  • ‌SSB在时域上的特征
  • RHCE-SElinux+防火墙
  • Web Broker(Web服务应用程序)入门教程(5)
  • 软考高级之系统架构师之安全攻防技术
  • 固定VMwareIP地址
  • 【Vue】Vue项目创建步骤
  • 无线配置实验
  • 淘宝 API 多语言接入:释放技术开发新潜力
  • DNS域名系统
  • C语言编译所有知识点