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

如何在Spring项目中获取其他独立项目的ApplicationContext

跨独立Spring项目获取ApplicationContext实现方案

以下方案均适配标准HotSpot虚拟机,不需要修改原有依赖Jar,不需要做字节码增强新增类字段/方法。

按部署场景选择对应实现

场景1:两个项目运行在同一个JVM进程内(如同Tomcat容器下多Web应用、同进程启动多个Spring容器)

这种场景不需要跨进程通信,通过共享类路径下的静态持有类即可实现,步骤如下:

  • 将如下工具类放在两个项目共同的上层共享类路径下(比如Tomcat的lib目录、进程级公共依赖目录),不要放在任意一个项目的私有类加载路径中,避免类加载器隔离导致静态变量不互通:
import org.springframework.context.ApplicationContext;
public class SharedAppContextHolder {
    private static volatile ApplicationContext targetContext;
    public static void bind(ApplicationContext ctx) {
        targetContext = ctx;
    }
    public static ApplicationContext get() {
        return targetContext;
    }
}
  • 在被获取上下文的Spring项目中,注册一个容器回调,在容器启动完成后将自身ApplicationContext绑定到上述持有类中。如果无法修改该项目的代码和原有Jar,可以通过Java Agent的premain方法在启动时注入该回调逻辑;如果可以给项目增加配置类,直接注册如下Bean即可:
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ContextBindConfig {
    @Bean
    public BeanFactoryPostProcessor bindContextPostProcessor() {
        return beanFactory -> {
            if (beanFactory instanceof ApplicationContext ctx) {
                SharedAppContextHolder.bind(ctx);
            }
        };
    }
}
  • 在需要获取上下文的项目中,直接调用SharedAppContextHolder.get()即可拿到目标项目的ApplicationContext实例。

注意:如果存在类加载器隔离机制,必须保证SharedAppContextHolder由公共上层类加载器加载,否则两个项目加载到的Holder类是不同的类,静态变量无法共享。

场景2:两个项目是独立JVM进程部署(跨进程)

跨JVM场景下不存在直接获取另一个JVM堆内存中对象引用的可能,不需要尝试JNI、直接对象暴露这类方案,通过间接通信的方式实现即可:

  • 方案1:自定义JMX MBean实现访问。不要直接暴露ApplicationContext实例(该类内部持有大量不可序列化、类加载隔离的依赖,默认无法通过JMX传递),而是在被访问项目中定义标准MBean,封装需要的ApplicationContext操作能力(比如按名称/类型获取Bean、调用Bean方法等),调用方通过JMX连接到目标进程后调用MBean方法,间接操作目标上下文。
  • 方案2:注入轻量通信端点。如果无法修改被访问项目的代码,可以通过Java Agent在目标项目启动时注册Spring容器监听器,等容器启动完成拿到ApplicationContext后,绑定一个轻量HTTP/RMI端点,调用方通过网络请求访问端点即可操作目标上下文。

之前尝试方案的问题说明

  • ASM增强SpringApplication新增字段/方法:标准HotSpot虚拟机的类重定义机制不允许运行时修改类结构(新增字段、方法、父类等),仅DCEVM这类定制虚拟机支持该特性,普通生产环境不需要走这个方向。
  • 修改Jar包实现:上述方案完全不需要侵入原有依赖Jar,没有必要走修改Jar的重打包路线。
  • JMX直接暴露ApplicationContext:JMX本身支持传递对象,但ApplicationContext属于复杂容器对象,内部依赖大量未实现序列化、且受类加载器隔离的组件,直接传递必然失败,属于用法问题而非JMX能力问题。
  • JNI方案:JNI仅能操作当前进程JVM的内存对象,跨进程场景下完全无法访问其他JVM的堆内存,同进程场景下也不需要用JNI做上下文传递。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 18:57:18