我正在一个 Servlet 3.0+ 环境下运行 Spring 应用程序,使用所有 Java 配置来编程配置 Servlet 上下文。我的问题(详细信息如下):如何构建项目以支持根和 Web 应用程序上下文的组件扫描,而不重复初始化组件?
据我所知,有两个要注册 Spring Bean 的上下文。首先,根上下文是非与 Servlet 相关的组件所在的位置。例如批处理作业、DAO 等。其次,Servlet 上下文是 Servlet 相关组件所在的位置,例如控制器、过滤器等。
我实现了一个 WebApplicationInitializer 来注册这两个上下文,就像 WebApplicationInitializer 中的 JavaDoc 指定的那样,使用 AppConfig.class 和 DispatcherConfig.class。
我希望两者都可以自动查找它们各自的组件,因此我为两者都添加了 @ComponentScan(这导致我的 Hibernate 实体被初始化两次)。Spring 通过扫描某个指定的基础包来查找这些组件。那么,这是否意味着我需要将所有 DAO 相关的对象放在一个与控制器不同的包中?如果是这样的话,那就很不方便了,因为我通常会按功能(而不是按类型)进行打包。
代码片段...
WebApplicationInitializer:
public class AppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) throws ServletException {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext =
new AnnotationConfigWebApplicationContext();
dispatcherContext.register(WebAppConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
AppConfig:
@Configuration
@ComponentScan
public class AppConfig {
}
WebAppConfig:
@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
@ComponentScan(basePackageClasses = AppConfig.class)
public class WebAppConfig extends WebMvcConfigurerAdapter {
}
Filter
。 - M. Deinum