我们的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上下文之间的父子关系。
答案 0 :(得分:1)
使用include
过滤器时,并不会自动表示默认设置已禁用。默认情况下,@ComponentScan
将检测所有@Component
类,无论include
指定的是什么。因此,如果您想明确控制要扫描的注释,首先必须禁用默认值。要将useDefaultFilters
的{{1}}属性设置为@ComponentScan
。
false
现在它只会检测@ComponentScan(
basePackages = {"blah"},
useDefaultFilters=false,
includeFilters = @Filter(type = FilterType.ANNOTATION, classes={Controller.class})
)
带注释的bean。