Весна: как AnnotationConfigWebApplicationContext не может перезаписать более поздние компоненты? - PullRequest
2 голосов
/ 08 июня 2011

У меня есть веб-приложение, которое использует фреймворк Sring IoC.Я использую конфигурацию Java для Spring, и я использую только определение модуля с пометкой @Configuration (в других местах кода нет связанных с DI тегов).

Реестр Spring создается при запуске веб-приложения благодаря (немного измененной версии) прослушивателю загрузчика контекста Spring и параметру contextConfigLocation в файле web.xml, настроенному для указания на@Configuration аннотированный класс.

Все это хорошо, и я получаю AnnotationConfigWebApplicationContext.

Теперь я хочу, чтобы в моем приложении были плагины, которые будут иметь свои собственные @Configuration аннотированные классы конфигурации,и будет использовать некоторые из основных служб приложений. НО Я не хочу, чтобы основное приложение модифицировалось для загрузки этих новых модулей.

Итак, я подумал, что я мог бы просто использовать поиск пакетов аннотированного класса для этого, нотеперь кажется, что я могу использовать два bean-компонента одного типа, даже если они имеют разные идентификаторы, и ясно, что документ AnnotationConfigWebApplicationContext заявляет, что:

Примечание: в случае нескольких классов @Configuration, позже @Bean определения будут заменять определения, определенные в ранее загруженных файлах.Это можно использовать для преднамеренного переопределения определенных определений bean-компонентов через дополнительный класс Configuration.

Я не хочу этого, потому что модули должны иметь возможность предоставлять альтернативную версию сервисов, а не (всегда) переопределять существующую - особенно, если я хочу иметь компонент "moduleDef".

Я пытался использовать разные подходы к этому, но иерархия Context и связанных сервисов для меня просто велика.

Итак, кто-нибудь знает, как я могу достичь своей цели?

Спасибо

1 Ответ

3 голосов
/ 08 июня 2011

Вы можете иметь несколько бобов одного типа , но вы не можете иметь 2 или более бинов с идентификатором водин Spring ApplicationContext - независимо от того, используете ли вы XML или JavaConfig.

Механизм переопределения соответствует идентификаторам бина, поэтому все, что вам нужно сделать, - это обеспечить уникальный идентификатор, то есть: coreModuleDef, someOtherModuleDef,anotherModuleDef.Я не думаю, что вам нужно, чтобы идентификатор каждого определения модуля был идентичным?Для этого достаточно, чтобы тип был одинаковым, но не идентификатором.

Вы также можете отключить механизм переопределения, установив allowBeanDefinitionOverriding в false на вашем AnnotationConfigWebApplicationContext, чтобы получить исключение, если выслучайно переопределить бин:

public class MyDispatcherServlet extends DispatcherServlet {
    @Override
    protected void postProcessWebApplicationContext(
            ConfigurableWebApplicationContext wac) {

        ((AnnotationConfigWebApplicationContext) wac)
            .setAllowBeanDefinitionOverriding(false);
    }
}

или:

public class MyContextLoaderListener extends ContextLoaderListener {
    @Override
    protected void customizeContext(
            ServletContext servletContext,
            ConfigurableWebApplicationContext applicationContext) {

        ((AnnotationConfigWebApplicationContext) wac)
            .setAllowBeanDefinitionOverriding(false);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...