确保从非弹簧环境加载春豆

use*_*900 8 java spring servlets classloader autowired

我有弹簧应用程序(球衣2.6类和servlet).

我需要从泽西/非弹簧环境中获取Spring bean(s),

类似的问题建议在上下文的静态包装中获取上下文

public static ApplicationContext getContext() {
    return context;
}
Run Code Online (Sandbox Code Playgroud)

如何确定上下文已加载或不为null?

如果我不能,我应该等待/检查,直到它加载弹簧上下文?

在从泽西上下文调用或从简单的HttpServlet代码调用bean的情况下

编辑

Jersey使用jersey-spring3依赖jar 工作正常,所以我的问题只是关于Servlets的Spring控件

编辑2

该应用程序正在加载不同于@entpnerd建议文章的弹簧

它注册了一个实现的Servlet WebApplicationInitializer

public class MyWebAppInitializer implements WebApplicationInitializer {
Run Code Online (Sandbox Code Playgroud)

但是也在DispatcherServletweb.xml中配置了

如何才能DispatcherServlet在Spring加载后加载?

因为我们在其init方法上添加了自动装配功能:

WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext())
                    .getAutowireCapableBeanFactory().autowireBean(this);
Run Code Online (Sandbox Code Playgroud)

在提供请求之前添加超时是最喜欢的解决方案还是在类加载中有一个可以处理它的调整?

编辑3

我找到了注入的答案答案,但不是为什么在Servlet之前加载Spring.

Mar*_*nik 5

这个想法很简单,虽然实际的实现可能会有所不同,具体取决于Spring引导和Jersery初始化的确切方式.

一个主意:

Spring启动,作为一个纯粹的运行时框架,就是正确加载应用程序上下文(从问题的角度来看).

所以,底线,当它加载时,内存中有一个应用程序上下文,并且可以从这个应用程序上下文中访问bean.

现在,既然你说Jersey不是spring/spring-boot驱动的,那么这个应用程序上下文必须可以通过Jersey的某种静态全局变量来访问,它非常难看但是应该可行.

所以这个想法有两个步骤:

  1. 将应用程序上下文引用放到可从Jersey访问的某个静态持有者.
  2. 在Jersey组件的某些基础架构级代码中读取此值.

可能的实施

从技术上讲,第一步可以通过实现某种弹簧启动监听器来完成,该监听器将应用程序上下文存储在某种单例中:

enum ApplicationContextHolder {
   INSTANCE;
    private ApplicationContext ctx;
    void setApplicationContext(ApplicationContext ctx) {
        this.ctx = ctx;
    }

    ApplicationContext getCtx() {
        return this.ctx;
    }

}


// and a listener (spring boot provides many ways to register one, but the 
// implementation should be something like this):
// The main point is that its managed by spring boot, and hence and access to 
// the application context
class StartupListener implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {           
             ApplicationContextHolder
             .INSTANCE
             .setApplicationContext(event.getApplicationContext());
    }
}
Run Code Online (Sandbox Code Playgroud)

现在第2步是:

class MyJerseyOrWhateverComponentThatWantsToAccessApplicationContext {

    public void foo() {
       ApplicationContext ctx = ApplicationContextHolder.INSTANCE.getCtx();
       ... 
       ctx.getBean(...);
    }
}
Run Code Online (Sandbox Code Playgroud)