我是Spring Java配置的新手,并且想知道一些事情。
传统的Spring Web应用程序有两种不同的上下文,即根应用程序上下文和调度程序servlet上下文。根上下文基本上包含服务层之前的所有内容(持久性配置,如JPA和数据访问层)以及包含所有MVC和其他与Web相关的事物的servlet上下文。
Web上下文继承自根上下文,因此Web组件可以在根上下文中访问bean,但不能相反。
使用无XML配置和org.springframework.web.WebApplicationInitializer
的现代方法,有两个不同的上下文仍然有意义吗?
让一些注释@Configuration
类按层重组(例如一个用于数据访问层,一个用于服务层,一个用于Web层)并在同一个上下文中加载所有这些类似乎更简单,像这样:
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("/");
}
}
但是,我已经看到了仍然创建根上下文的示例,并使用org.springframework.web.context.ContextLoaderListener
管理其生命周期:
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模块),第二种方法是否带来了平衡额外复杂性的任何具体好处?什么是最佳做法?
答案 0 :(得分:1)
您正在寻求建议,但距离意见不远。这个答案是我对春天哲学的理解。
Spring 允许为非MVC部分和MVC部分使用不同的上下文,建议这样做,因为关注点分离(*)被认为是良好的做法。它从不强迫开发者去做。
你可以将所有内容放在java配置的单个上下文中,与使用XML完成相同的操作
由您来了解该伪规则(2个上下文)是否与您的应用程序相关。如果您以后可以从Spring MVC迁移到另一个框架,那么 相关。如果您在一个大型组织中工作,其中不同的开发人员可以在MVC部分和非MVC部分上工作,那么 相关。如果它是一个非常简单的应用程序,只有一个单独的开发人员,并且很少有预期的演变,那么您当然可以将最佳实践与简单交换。
规则只是指导原则,开发人员必须知道必须遵守的时间以及何时可以忽略它们。它实际上取决于一般背景,项目规模,组织和一般经验。
(*)将模型部分(服务和持久性)与VC部分(用户界面)分开被认为是好的,因为:
答案 1 :(得分:0)
1)每个应用程序的一个上下文可能只是Singleton反模式的另一个转世。基本上它是你的东西的单一范围,当你有很多bean,特别是模糊的依赖,它很快就会导致问题。
2)你可以根据需要实时构建和销毁子上下文,从而对长期存在的对象,事件层次结构等不太关心(尽管不是简单的webapps需要的东西)。