春季 Web 应用程序启动 - @ComponentScan - 应用程序上下文和 Web 上下文



我们的Spring MVC Web应用程序正在尝试遵循推荐的样式。它使用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 {

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

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

(上述类位于一个单独的包中,该包是"blah"的同级;没有进行自我扫描)。

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

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

Creating shared instance of singleton bean 'labelDao'

我错过了什么吗?

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

使用include筛选器时,这并不自动意味着默认值被禁用。默认情况下,@ComponentScan将检测所有@Component类,而不管 yu 在include中指定了什么。因此,如果要显式控制要扫描的注释,则首先必须禁用默认值。为此,请将@ComponentScanuseDefaultFilters属性设置为 false

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

现在它只会检测@Controller注释的豆子。

相关内容

最新更新