将单例注入 Spring Boot 应用程序上下文

Posted

技术标签:

【中文标题】将单例注入 Spring Boot 应用程序上下文【英文标题】:Injecting singletons in to a Spring Boot Application Context 【发布时间】:2017-12-20 17:10:56 【问题描述】:

我想将一些非 Spring 托管的 bean 注入到 Spring Boot 应用程序中。我原以为这样做的方法是:

    GenericApplicationContext parentContext = new StaticApplicationContext();
    parentContext.getBeanFactory().registerSingleton("pipeline", pipeline);
    parentContext.refresh();   // seems to be required sometimes

    ApplicationContext context = new SpringApplicationBuilder()
            .sources(parentContext)
            .child(DispatcherApplication.class)
            .run();

但是,您只能将 Class<?>...Object... 传递给构建器上的 sources 方法,在后一种情况下,它识别的唯一值是:

Class - 要由 AnnotatedBeanDefinitionReader 加载的 Java 类 Resource - 由 XmlBeanDefinitionReader 加载的 XML 资源,或由 GroovyBeanDefinitionReader 加载的 groovy 脚本 Package - 由 ClassPathBeanDefinitionScanner 扫描的 Java 包 CharSequence - 适当加载的类名、资源句柄或包名。

那么我该如何传入父上下文实例,或者在启动前将单例注入 Spring Boot 应用程序?

TIA

【问题讨论】:

【参考方案1】:

您不必使用应用程序生成器使用修改后的上下文创建应用程序。

只需确保您自动装配 parentContext 并在派生自它的工厂上注册单例

【讨论】:

抱歉,我不确定我是否完全关注您的答案,请您扩展一下吗?【参考方案2】:

由于或多或少与您所说的相同原因,我无法让您的父上下文方法起作用。相反,我:

@Lazy@Autowired注释bean 创建一个匿名ApplicationListener 在监听器调用getBeanFactory().registerSingleton() 使用setListener()将监听器添加到应用程序

这是精简的监听器:

    public void onApplicationEvent(ApplicationEvent event) 
        if (event instanceof ContextRefreshedEvent) 
            ((GenericApplicationContext) (((ContextRefreshedEvent) event)
                    .getApplicationContext()))
                    .getBeanFactory().registerSingleton("legacyBean", obj);
        
    

我没有找到太多关于应用程序生命周期的文档,但至少我所做的大部分工作都是标准的。但是,它确实依赖于 GenericApplicationContext 的上下文转换,它“对我有用”(Spring Boot 1.4.1)并且看起来很安全,但理论上可能会在未来的版本中改变

我的完整来源博客文章: http://blog.nqzero.com/2018/01/integrating-spring-with-legacy-app.html

【讨论】:

以上是关于将单例注入 Spring Boot 应用程序上下文的主要内容,如果未能解决你的问题,请参考以下文章

无法在使用 @ExtendWith(SpringExtension.class) 运行的 Spring Boot 单元测试中注入应用程序上下文

spring boot 动态注入bean

带有 testcontainers 和 jOOQ 的 Spring Boot 不会注入 DSL 上下文

在Spring上下文中的原型bean中的单例bean

Spring实战407---Bean的作用域

将单例对象保存到磁盘 - 本机 Iphone 应用程序