Spring web app启动 - @ComponentScan - 应用程序上下文和Web上下文

时间:2016-02-23 21:13:41

标签: spring spring-mvc default startup component-scan

我们的Spring MVC网络应用程序正在尝试遵循推荐的风格。它使用AppContext(ContextLoaderListener)来存储DAO和服务。它使用WebAppContext(DispatcherServlet)来存储控制器。

DAO对象进入两者 AppContext和WebAppContext。我不明白为什么。

AppContext配置应该加载除Controllers之外的所有东西(以及一个将代码表加载到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 {

并且Web部件应该仅加载控制器:

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

(上面的类是在一个单独的包中,它是'blah'的兄弟姐妹;没有自我扫描正在进行。)

当然,控制器引用DAO对象。在Controller中,那些DAO对象是@Autowired

我的期望是从AppContext检索那些@Autowired DAO对象,而不是第二次创建,并放在WebAppContext中。但我认为他们是第二次创造。例如,此行在日志中出现两次,一次用于AppContext,一次用于WebAppContext:

Creating shared instance of singleton bean 'labelDao'

我错过了什么吗?

就好像缺少根上下文和Web上下文之间的父子关系。

1 个答案:

答案 0 :(得分:1)

使用include过滤器时,并不会自动表示默认设置已禁用。默认情况下,@ComponentScan将检测所有@Component类,无论include指定的是什么。因此,如果您想明确控制要扫描的注释,首先必须禁用默认值。要将useDefaultFilters的{​​{1}}属性设置为@ComponentScan

false

现在它只会检测@ComponentScan( basePackages = {"blah"}, useDefaultFilters=false, includeFilters = @Filter(type = FilterType.ANNOTATION, classes={Controller.class}) ) 带注释的bean。