Spring 网络应用程序启动 - @ComponentScan - 应用程序上下文和网络上下文
Spring web app start up - @ComponentScan - app context and web context
我们的 Spring MVC 网络应用正在尝试遵循推荐的样式。它使用 AppContext (ContextLoaderListener
) 来存储 DAO 和服务。它使用 WebAppContext (DispatcherServlet
) 来存储控制器。
DAO 对象正在进入 AppContext 和 WebAppContext。我不明白为什么。
AppContext 配置应该加载除控制器之外的所有内容(以及将代码表加载到 ServletContext 中的 class):
@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 {
(上面的 classes 在一个单独的包中,它是 'blah' 的兄弟包;没有进行自扫描)。
当然,控制器引用 DAO 对象。在 Controller 中,那些 DAO 对象是 @Autowired
。
我的期望是那些 @Autowired
DAO 对象是从 AppContext 中检索的,而不是第二次创建的,而是放在 WebAppContext 中的。但我认为它们是第二次创建的。例如,这一行在日志中出现了两次,一次是针对 AppContext,一次是针对 WebAppContext:
Creating shared instance of singleton bean 'labelDao'
我是不是漏掉了什么?
好像根上下文和网络上下文之间的父子关系丢失了。
当使用 include
过滤器时,并不自动意味着默认设置被禁用。默认情况下,@ComponentScan
将检测所有 @Component
类,而不管 include
指定的是什么。因此,如果您想明确控制要扫描的注释,您首先必须禁用默认值。将 @ComponentScan
的 useDefaultFilters
属性设置为 false
。
@ComponentScan(
basePackages = {"blah"},
useDefaultFilters=false,
includeFilters = @Filter(type = FilterType.ANNOTATION, classes={Controller.class})
)
现在它只会检测 @Controller
个带注释的 bean。
我们的 Spring MVC 网络应用正在尝试遵循推荐的样式。它使用 AppContext (ContextLoaderListener
) 来存储 DAO 和服务。它使用 WebAppContext (DispatcherServlet
) 来存储控制器。
DAO 对象正在进入 AppContext 和 WebAppContext。我不明白为什么。
AppContext 配置应该加载除控制器之外的所有内容(以及将代码表加载到 ServletContext 中的 class):
@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 {
(上面的 classes 在一个单独的包中,它是 'blah' 的兄弟包;没有进行自扫描)。
当然,控制器引用 DAO 对象。在 Controller 中,那些 DAO 对象是 @Autowired
。
我的期望是那些 @Autowired
DAO 对象是从 AppContext 中检索的,而不是第二次创建的,而是放在 WebAppContext 中的。但我认为它们是第二次创建的。例如,这一行在日志中出现了两次,一次是针对 AppContext,一次是针对 WebAppContext:
Creating shared instance of singleton bean 'labelDao'
我是不是漏掉了什么?
好像根上下文和网络上下文之间的父子关系丢失了。
当使用 include
过滤器时,并不自动意味着默认设置被禁用。默认情况下,@ComponentScan
将检测所有 @Component
类,而不管 include
指定的是什么。因此,如果您想明确控制要扫描的注释,您首先必须禁用默认值。将 @ComponentScan
的 useDefaultFilters
属性设置为 false
。
@ComponentScan(
basePackages = {"blah"},
useDefaultFilters=false,
includeFilters = @Filter(type = FilterType.ANNOTATION, classes={Controller.class})
)
现在它只会检测 @Controller
个带注释的 bean。