You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Spring Java配置动态加载启动后加入classpath的jar中Bean?

问题原因分析
  • 你调用refresh()方法的操作是问题核心:Spring应用上下文的refresh()是初始化上下文的全生命周期方法,已经完成初始化的上下文重复调用该方法时,会先销毁所有已创建的Bean(包括内置Web服务器、已注册的接口、业务Bean等),再重新走初始化流程,所以会直接停掉你正在运行的Web应用。
可行解决方案

不需要调用全量refresh(),只需要触发配置类的解析和新Bean的注册流程即可,示例代码如下:

import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;

// 加载外部Jar中的配置类,注意类的全限定名要和实际配置类一致
Class<?> confClass = jarService.loadClass("com.transportexchangegroup.testConf.AppConf");
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) applicationContext.getAutowireCapableBeanFactory();

// 1. 注册配置类的BeanDefinition
AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(confClass);
registry.registerBeanDefinition(confClass.getSimpleName(), configBeanDef);

// 2. 利用Spring自带的配置类处理器解析配置,自动处理@ComponentScan、@Bean等注解,完成所有相关Bean的定义注册
ConfigurationClassPostProcessor configProcessor = applicationContext.getBean(ConfigurationClassPostProcessor.class);
configProcessor.postProcessBeanDefinitionRegistry(registry);

// 3. 实例化所有新注册的非懒加载Bean
applicationContext.getAutowireCapableBeanFactory().preInstantiateSingletons();

注意事项

  • 加载外部Jar的类加载器需要以当前Spring上下文的类加载器为父加载器,避免出现类隔离导致的类转换异常。
  • 如果配置类依赖上下文已有的Bean,不需要额外处理,解析过程中会自动完成依赖注入。
RestController加载说明

上述方案可以正常加载Jar包中的@RestController:配置类的@ComponentScan会扫描到Controller类并完成Bean注册,Spring MVC默认的RequestMappingHandlerMapping会自动检测到新注册的Controller,自动完成接口路径的映射,不需要额外配置即可正常访问接口。

内容的提问来源于stack exchange,提问作者Arthur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 21:48:00