Как встроить Jetty в Spring и использовать тот же AppContext, в который он был встроен? - PullRequest
9 голосов
/ 02 июля 2010

У меня есть Spring ApplicationContext, где я объявляю серверный компонент Jetty и запускаю его. Внутри Jetty у меня есть DispatcherServlet и пара контроллеров. Как сделать так, чтобы DispatcherServlet и его контроллеры использовали бины из того же ApplicationContext, где объявлен Jetty?

На самом деле, в этом внешнем контексте у меня есть пара демоноподобных bean-компонентов и их зависимостей. Контроллеры внутри Jetty используют одинаковые зависимости, поэтому я бы хотел избежать дублирования их внутри и снаружи Jetty.

1 Ответ

5 голосов
/ 02 июля 2010

Я делал это некоторое время назад.

В документации Spring предлагается использовать ContextLoaderListener для загрузки контекста приложения для сервлетов. Вместо этого класса 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);
    }

}

Это немного грязно, и, вероятно, может быть улучшено, но это сработало для меня.

...