如何将Jetty嵌入到Spring中,并使其使用与嵌入的相同的AppContext?


问题内容

我有一个Spring
ApplicationContext,在其中声明Jetty服务器bean并启动它。在Jetty内部,我有一个DispatcherServlet和几个控制器。如何使DispatcherServlet及其控制器使用声明了Jetty的同一ApplicationContext中的bean?

实际上,在外部环境中,我有几个类似守护程序的bean及其依赖项。Jetty内的控制器使用相同的依赖项,因此我想避免在Jetty内外复制它们。


问题答案:

我前一阵子做了。

Spring的文档建议您使用ContextLoaderListener来加载servlet的应用程序上下文。代替这个Spring类,使用您自己的侦听器。这里的关键是,您的自定义侦听器可以在Spring配置中定义,并且可以知道其定义的应用程序上下文。因此,它无需加载新的应用程序上下文,而只是返回该上下文。

侦听器将如下所示:

public class CustomContextLoaderListener extends ContextLoaderListener implements BeanFactoryAware {

    @Override
    protected ContextLoader createContextLoader() {
        return new DelegatingContextLoader(beanFactory);
    }

    protected BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
       this.beanFactory = beanFactory;
    }

}

并且这样DelegatingContextLoader做:

public class DelegatingContextLoader extends ContextLoader {

    protected BeanFactory beanFactory;

    public DelegatingContextLoader(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    @Override
    protected WebApplicationContext createWebApplicationContext(ServletContext servletContext, ApplicationContext parent) throws BeansException {
        return new GenericWebApplicationContext((DefaultListableBeanFactory) beanFactory);
    }

}

有点混乱,可能可以改进,但这确实对我有用。