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

在Tycho Surefire测试环境中获取Spring注解上下文的问题

在Tycho Surefire测试环境中获取Spring注解上下文的问题

看起来你在Tycho测试环境下遇到了Spring Bean注入失败的问题——正常运行插件时没问题,但测试启动插件就报UnsatisfiedDependencyException,找不到ParseTextService的Bean。我来帮你梳理下可能的原因和解决办法:

一、先排查最基础的Bean扫描问题

首先确认你的ParseTextService类有没有标注@Service或者@Component注解?Spring只会扫描带有这些注解的类并注册成Bean,要是漏加了肯定找不到。另外检查@ComponentScan(basePackages = {"io.github.magwas"})的包路径,确保ParseTextService在这个包或者它的子包下面,测试环境的包结构有时候会和生产环境有细微差异,别大意。

二、调整Spring上下文的创建方式

你现在把ParserBundleActivator作为Spring的配置类来创建上下文,同时还在Activator里用@Autowired注入Bean,这其实有点冲突——Activator本身是OSGi的组件,不是Spring管理的Bean,Spring会尝试注入但时机可能不对。建议改成单独的Spring配置类:

@Configuration
@ComponentScan(basePackages = {"io.github.magwas"})
public class SpringConfig {
    // 可以在这里添加其他Bean配置
}

然后在Activator里这样初始化上下文:

@Override
public void start(BundleContext bundleContext) {
    // 先设置上下文类加载器
    Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
    
    // 初始化Spring上下文
    appContext = new AnnotationConfigApplicationContext();
    appContext.setClassLoader(this.getClass().getClassLoader()); // 明确指定类加载器
    appContext.register(SpringConfig.class);
    appContext.refresh();
    
    // 手动获取Bean,去掉原来的@Autowired注解
    parseText = appContext.getBean(ParseTextService.class);
    Assert.notNull(parseText, "parseText is null");
    
    // 注册OSGi服务
    ServiceRegistration<ParseTextService> registration = bundleContext.registerService(ParseTextService.class, parseText, new Hashtable<String, String>());
    System.err.println("registered ParseTextService:"+registration);
}

这样把Spring配置和OSGi Activator职责分开,逻辑更清晰,也能避免注入时机的问题。

三、处理OSGi类加载器隔离问题

Tycho测试基于Equinox OSGi,每个Bundle的类加载器是隔离的,你只设置当前线程的上下文类加载器可能不够,Spring内部的线程可能没继承这个加载器。上面的代码里已经给AnnotationConfigApplicationContext明确设置了类加载器,这能确保Spring用Bundle的类加载器去扫描Bean。

另外还要检查测试Bundle的MANIFEST.MF,确保Import-Package里包含了Spring相关的包(比如org.springframework.context.annotation、org.springframework.beans.factory.annotation),以及你的Bean所在的包(io.github.magwas.inez.parse),不然类加载器找不到这些类。

四、调整Tycho Surefire的Bundle启动顺序

Spring相关的Bundle必须在你的插件Bundle之前启动,不然你的插件启动时Spring还没初始化好。修改tycho-surefire的配置,添加Spring Bundle的启动设置:

<plugin>
    <groupId>org.eclipse.tycho</groupId>
    <artifactId>tycho-surefire-plugin</artifactId>
    <configuration>
        <bundleStartLevel>
            <!-- 先启动Spring核心Bundle -->
            <bundle>
                <id>org.springframework.context</id>
                <level>1</level>
                <autoStart>true</autoStart>
            </bundle>
            <bundle>
                <id>org.springframework.core</id>
                <level>1</level>
                <autoStart>true</autoStart>
            </bundle>
            <!-- 再启动你的插件Bundle -->
            <bundle>
                <id>io.github.magwas.inez.parser</id>
                <level>2</level>
                <autoStart>true</autoStart>
            </bundle>
        </bundleStartLevel>
        <!-- 如果是无UI的测试,添加这个配置 -->
        <useUIHarness>false</useUIHarness>
    </configuration>
</plugin>

这样能保证Spring先启动完成,你的插件启动时Spring上下文才能正常工作。

五、去掉Activator里的@Autowired注解

你现在既手动从上下文获取Bean,又用@Autowired注入,这会导致Spring尝试注入但Activator不是Spring管理的Bean,反而容易出问题。直接去掉@Autowired ParseTextService parseText这行,完全通过appContext.getBean()获取就好。

按照上面的步骤调整后,应该能解决测试环境下Spring找不到Bean的问题。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 09:19:35