Запуск веб-приложения Spring — @ComponentScan — контекст приложения и веб-контекст

Наше веб-приложение Spring MVC пытается следовать рекомендуемому стилю. Он использует AppContext (ContextLoaderListener) для хранения DAO и служб. Он использует WebAppContext (DispatcherServlet) для хранения контроллеров.

Объекты DAO попадают в оба AppContext и WebAppContext. Я не понимаю, почему.

Предполагается, что конфигурация AppContext загружает все, кроме контроллеров (и класса, который загружает кодовые таблицы в ServletContext):

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
@EnableTransactionManagement
@EnableScheduling
@ComponentScan(
  basePackages = {"blah"},
  excludeFilters = {
    @Filter(type = FilterType.ANNOTATION, value = {Controller.class}),
    @Filter(type = FilterType.ASSIGNABLE_TYPE, value = LoadOnStartup.class) 
  } 
)
public class SpringRootConfiguration {

и веб-часть должна загружать только контроллеры:

@Configuration
@EnableWebMvc
@ComponentScan(
 basePackages = {"blah"},
 includeFilters = @Filter(type = FilterType.ANNOTATION, classes={Controller.class})
)
public class SpringWebConfiguration extends WebMvcConfigurerAdapter {

(Вышеупомянутые классы находятся в отдельном пакете, который является братом «бла»; самосканирование не происходит).

Конечно, контроллеры ссылаются на объекты DAO. В контроллере этими объектами DAO являются @Autowired.

Я ожидал, что эти @Autowired объекты DAO извлекаются из AppContext, а не создаются во второй раз и помещаются в WebAppContext. Но я думаю, что они создаются во второй раз. Например, эта строка появляется в журнале дважды, один раз для AppContext и один раз для WebAppContext:

Creating shared instance of singleton bean 'labelDao'

Я что-то пропустил?

Как будто связь родитель-потомок между корневым контекстом и веб-контекстом отсутствует.


person John    schedule 23.02.2016    source источник
comment
Вам не хватает useDefaultFilters=false на SpringWebConfiguration. Включение чего-то не исключает автоматически все остальное, то есть значения по умолчанию.   -  person M. Deinum    schedule 24.02.2016
comment
Я не эксперт в Spring (даже близко), но... Я считаю, что beans/@Component/@Repository по умолчанию являются синглтонами. Это может помочь: stackoverflow.com/questions/28039901/   -  person kazbeel    schedule 24.02.2016
comment
@М. Deinum - это исправление ... Если вы добавите ответ (в отличие от комментария), я приму его как правильный.   -  person John    schedule 24.02.2016


Ответы (1)


При использовании фильтра include это не означает автоматически, что значения по умолчанию отключены. По умолчанию @ComponentScan будет обнаруживать все классы @Component, независимо от того, что вы укажете в include. Поэтому, если вы хотите явно контролировать, какие аннотации сканировать, вам сначала нужно отключить значения по умолчанию. Для этого установите для атрибута useDefaultFilters элемента @ComponentScan значение false.

@ComponentScan(
 basePackages = {"blah"},
 useDefaultFilters=false,
 includeFilters = @Filter(type = FilterType.ANNOTATION, classes={Controller.class})
)

Теперь он будет обнаруживать только @Controller аннотированных компонентов.

person M. Deinum    schedule 25.02.2016