在多模块Java-Config Spring MVC应用程序中使用@ComponentScan的正确方法

Ben*_*n M 6 spring spring-mvc maven multi-module spring-java-config

我刚刚开始了一个新的春季项目,这次我想做"正确"的事情.在上一个项目中,由于多个@ComponentScan注释,我遇到了多个注册某些类的问题.(即所有服务类都注册了两次)

基本上我使用以下布局:

WebAppInitializer:

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { RootConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { WebMvcConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

}
Run Code Online (Sandbox Code Playgroud)

RootConfig:

@Configuration
@ComponentScan
public class RootConfig {
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

WebMvcConfig:

@EnableWebMvc
@ComponentScan
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

DatabaseConfig:

@Configuration
@EnableJpaRepositories("my.base.class.path")
public class DataConfig {
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

第一个基本问题是: 哪个类应该扫描哪些类/注释?

应该只WebMvcConfig扫描@Controller课程吗?哪一个应该扫描,for @Servicefor for @Configuration和for @Component

第二个问题是: 或者我应该只使用包来缩小扫描路径?

例:

rootpackage
rootpackage.config.RootConfig
rootpackage.config.DatabaseConfig
rootpackage.mvc.WebMvcConfig
Run Code Online (Sandbox Code Playgroud)

然后将所有@Controller课程置于rootpackage.mvc.*

第三个问题是: RootConfig扫描更常见DatabaseConfig吗?或者我应该放在课堂DatabaseConfiggetRootConfigClasses方法里面WebAppInitializer

最后一个问题是: 在一个多模块项目中:你如何组织这些事情?

示例:如果我选择问题二中描述的方式,我可以说,应用程序的每个模块实际上都包含几个不同的模块.比方说,我想创建一个X具有@Service类和几个@Controller类的模块,我可以将它们放在不同的包中.像这样:

Maven Module X Service

rootpackage.services.x.XService
rootpackage.services.x.XServiceImpl
Run Code Online (Sandbox Code Playgroud)

Maven Module X Controller

rootpackage.mvc.controller.x.X1Controller
rootpackage.mvc.controller.x.X2Controller
rootpackage.mvc.controller.x.X3Controller
Run Code Online (Sandbox Code Playgroud)

如果你建议这样做,那么:在哪里放置模型和存储库(用于访问数据库)?我应该为每个模块创建一个新模块吗?

提前致谢!

Rom*_*ski 1

使用基于 XML 的配置,您通常会拥有 2 个上下文,一个父上下文将加载所有业务服务、数据库配置、存储库、域对象等,另一个用于加载控制器等的 Web 上下文。

两者都应该使用包来确保它们不会尝试加载相同的 bean 两次。您将两者都指定为ContextLoaderListener创建的ApplicationContext。

Web 应用程序上下文知道父级(而不是相反),并将在父级中搜索在其自己的上下文中找不到的任何 bean。这意味着您的控制器可以访问您的服务。

我没有在 Java 配置中这样做,但我认为方法是相同的