Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对于纯Java配置的SpringWebApp,有两个不同的上下文有意义吗?_Java_Spring_Spring Mvc_Spring Java Config - Fatal编程技术网

对于纯Java配置的SpringWebApp,有两个不同的上下文有意义吗?

对于纯Java配置的SpringWebApp,有两个不同的上下文有意义吗?,java,spring,spring-mvc,spring-java-config,Java,Spring,Spring Mvc,Spring Java Config,我是SpringJava配置新手,我想知道一些事情 传统上SpringWebApps有两种不同的上下文,根应用程序上下文和DispatcherServlet上下文。根上下文基本上包含服务层(持久性配置,如JPA和数据访问层)的所有内容,servlet上下文包含所有MVC和其他与web相关的内容 web上下文继承自根上下文,因此web组件可以访问根上下文中的bean,但不能访问相反的bean 在使用无XML配置和org.springframework.web.WebApplicationIniti

我是SpringJava配置新手,我想知道一些事情

传统上SpringWebApps有两种不同的上下文,根应用程序上下文和DispatcherServlet上下文。根上下文基本上包含服务层(持久性配置,如JPA和数据访问层)的所有内容,servlet上下文包含所有MVC和其他与web相关的内容

web上下文继承自根上下文,因此web组件可以访问根上下文中的bean,但不能访问相反的bean

在使用无XML配置和
org.springframework.web.WebApplicationInitializer
的现代方法中,使用两种不同的上下文是否仍然有意义

似乎更简单的做法是,只需使用几个带注释的
@Configuration
类按层重新组合bean(例如,一个用于数据访问层,一个用于服务层,一个用于web层),并在相同的上下文中加载所有bean,如下所示:

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {

        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherServletContext = new AnnotationConfigWebApplicationContext();
        dispatcherServletContext.register(MyPersistenceConfig.class, MyServicesConfig.class, MyMvcConfig.class);

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherServletContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }

}
public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {

        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(MyPersistenceConfig.class, MyServicesConfig.class);

        // Manage the lifecycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));

        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherServletContext = new AnnotationConfigWebApplicationContext();
        dispatcherServletContext.register(MyMvcConfig.class);

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherServletContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}
但是,我看到过一些示例,其中仍然创建了根上下文,并使用
org.springframework.web.context.ContextLoaderListener管理其生命周期,如下所示:

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {

        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherServletContext = new AnnotationConfigWebApplicationContext();
        dispatcherServletContext.register(MyPersistenceConfig.class, MyServicesConfig.class, MyMvcConfig.class);

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherServletContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }

}
public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {

        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(MyPersistenceConfig.class, MyServicesConfig.class);

        // Manage the lifecycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));

        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherServletContext = new AnnotationConfigWebApplicationContext();
        dispatcherServletContext.register(MyMvcConfig.class);

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherServletContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}

对于一个简单的webapp(单maven模块),第二种方法是否带来了平衡额外复杂性的具体好处?最佳做法是什么?

你在征求意见,但离意见不远。这就是我对春天哲学的理解

Spring允许对非MVC部件和MVC部件使用不同的Contexte,并建议这样做,因为关注点分离(*)被认为是一种良好的实践。它从不强迫开发人员这样做

在java配置中,您可以将所有内容放在单个上下文中,这与使用XML所做的完全相同

这取决于您是否知道该伪规则(2个contextes)与您的应用程序相关。如果您以后可以从SpringMVC转移到另一个框架,那么它就与之相关。如果您在一个大型组织中工作,不同的开发人员可以在MVC部件和非MVC部件上工作,那么是相关的。如果它是一个非常简单的应用程序,只有一个开发人员,并且几乎没有预期的发展,那么您当然可以与简单性交换最佳实践

规则只是指导原则,开发人员必须知道什么时候必须遵守规则,什么时候可以忽略规则。这实际上取决于总体环境、项目规模、组织结构和总体经验

(*)将模型部分(服务和持久性)与VC部分(用户界面)分离被认为是好的,因为:

  • 您(理论上)可以在保留模型部分的同时更改UI部分(从传统WebApp迁移到胖客户端只是将UI更改为最小的RESTfull界面)
  • 您可以尽可能少地开发和测试不同的层
  • 您可以在模型和ViewController部件上组建不同的团队,并将职责进行清晰的分离
  • 它可以由公司规则强制执行
1)每个应用程序的一个上下文可能会成为单身反模式的另一个转世。基本上,它是你的东西的单一作用域,当你有很多bean,特别是不明确的依赖项时,它很快就会导致问题


2) 您可以根据需要实时构建和销毁子上下文,从而减少对长期存在的对象、事件层次结构等的关注(尽管这不是简单的Web应用程序所需要的)

谢谢Serge给出的一般答案。但我希望能从单独的上下文中获得更多类似于特定优势列表的东西,例如,我可以想到“您可以独立于web框架为您的服务层构建单元测试”,或者,如您所述,“您可以在将来更轻松地切换web framework”。如果你用那种方式编辑你的问题,我会接受你的答案。