首页 > 解决方案 > 将遗留单例添加到 Spring ApplicationContext 以进行注入

问题描述

我正在尝试围绕遗留 Java 库创建一个轻量级 Web 服务,以使用 Spring Boot 将其公开为 Web 服务。我是 Spring 新手,虽然我有很多编写库的 Java 经验,但我所有的 Web 服务经验都在 ASP.NET 中。

我可以实例化我的库对象的一个​​实例,但我不知道如何@Autowired在启动应用程序时将该对象注入到我的控制器中。

这是我的主要应用程序:

@SpringBootApplication
public class ResolverWebServiceApplication {
    
    private static ArgumentParser newArgumentParser() {
        ArgumentParser parser = ArgumentParsers.newFor("Resolver").build();
        // configuring the parser
        return parser;
    }

    public static void main(String[] args) throws ArgumentParserException {
        
        ArgumentParser parser = newArgumentParser();
        Namespace ns = parser.parseArgs(args);
        ResolverOptions options = new ResolverOptions.Builder(ns)
                .build();
        ResolverContext context = new ResolverContext(options);
        // ^^^ I need to get this injected into my controllers ^^^
        
        SpringApplication.run(ResolverWebServiceApplication.class, args);
    }

}

然后是一个需要注入类的简单控制器:

@RestController
public class VersionController {
    
    @Autowired
    private ResolverContext context; // And here the instance needs to be injected.

    @GetMapping(path = "/version", produces = MediaType.APPLICATION_JSON_VALUE)
    public long version() {
                
        return context.getResolver().getVersionAsLong();
    }
}

我可以使上下文成为控制器仅引用的单例,但我希望能够通过模拟上下文来测试我的控制器。显然还需要添加很多验证和错误处理。

我不能让它成为一个 Bean,因为我只想为我的整个应用程序实例化一个。

我发现的最接近的问题是:在应用程序启动时将实例注册为“单例”bean。但是我不能将选项放在配置文件中。应用程序可能在容器或用户机器上启动,并且需要能够接受参数来初始化库类。如果有人必须为这些选项手动编辑应用程序配置,那将是真正的可用性下降。

标签: springspring-bootdependency-injection

解决方案


您需要告诉spring在初始化应用程序上下文时考虑您的lib中所需的类,即配置并让spring知道如何创建一个bean,然后让spring为您处理依赖注入。

首先,在您当前的项目中添加您在构建文件中所需的 jar,例如 maven 的 pom.xml。想法是在构建项目时将它放在类路径中。

正如你所说,它是遗留库,我假设它不是弹簧豆,那么

在您的配置类中,使用 @Bean 注释将其作为 bean 返回。

@Configuration
public class YourConfigurationClass {    

@Bean
SomeBean returnSomeBeanFromLegacyLib() {
    return new SomeClassFromLib();
}

一旦你从你的配置中返回这个 bean,它应该可以被 Spring Context 用于依赖注入,无论你@Autowire 所需的依赖。


推荐阅读