使用Java配置的Spring root和servlet上下文

Cor*_*rey 4 spring spring-mvc

我正在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("/");
    }

}
Run Code Online (Sandbox Code Playgroud)

AppConfig的:

@Configuration
@ComponentScan
public class AppConfig {
}
Run Code Online (Sandbox Code Playgroud)

WebAppConfig:

@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
@ComponentScan(basePackageClasses = AppConfig.class)
public class WebAppConfig extends WebMvcConfigurerAdapter {
}
Run Code Online (Sandbox Code Playgroud)

M. *_*num 10

只需在每个配置中定义要扫描的内容.通常,您的根配置应扫描除@Controllers以外的所有内容,并且您的Web配置应仅检测@Controllers.

您可以使用注释的includeFiltersexcludeFilters属性来完成此操作@ComponentScan.使用包含过滤器时,在这种情况下,您还需要通过设置useDefaultFilters为禁用默认过滤器false.

@Configuration
@ComponentScan(excludeFilters={@Filter(org.springframework.stereotype.Controller.class)})
public class AppConfig {}
Run Code Online (Sandbox Code Playgroud)

并为你的 WebConfig

@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
@ComponentScan(basePackageClasses = AppConfig.class, useDefaultFilters=false, includeFilters={@Filter(org.springframework.stereotype.Controller.class)})
public class WebAppConfig extends WebMvcConfigurerAdapter {}
Run Code Online (Sandbox Code Playgroud)

此外,您还需要导入@Filter注释:

import static org.springframework.context.annotation.ComponentScan.Filter;
Run Code Online (Sandbox Code Playgroud)