我偶尔会混淆这两个概念-WebApplicationInitializer和ApplicationContextInitializer,并希望描述它们中的每一个,以便为我自己澄清它们。
我以前在这里写过有关WebApplicationInitializer的博客。 它仅在符合Servlet 3.0+规范的Servlet容器中相关,并提供了一个挂钩以编程方式配置Servlet上下文。 这将如何帮助您-您可以拥有一个可能没有任何web.xml文件的Web应用程序,该文件通常在基于Spring的Web应用程序中用于描述根应用程序上下文以及称为DispatcherServlet的Spring Web前端控制器。 以下是使用WebApplicationInitializer的示例:
public class CustomWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{RootConfiguration.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{MvcConfiguration.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
现在,什么是ApplicationContextInitializer 。 本质上是在完全创建Spring应用程序上下文之前执行的代码。 使用ApplicationContextInitializer的一个好用例是按照以下方式以编程方式设置Spring环境配置文件:
public class DemoApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext ac) {
ConfigurableEnvironment appEnvironment = ac.getEnvironment();
appEnvironment.addActiveProfile("demo");
}
}
如果您有一个基于Spring-Boot的应用程序,那么注册ApplicationContextInitializer非常简单:
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class SampleWebApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(SampleWebApplication.class)
.initializers(new DemoApplicationContextInitializer())
.run(args);
}
}
但是,对于非Spring-Boot Spring应用程序而言,它有些棘手,如果它是web.xml的编程配置,则该配置遵循以下原则:
public class CustomWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(RootConfiguration.class);
ContextLoaderListener contextLoaderListener = new ContextLoaderListener(rootContext);
container.addListener(contextLoaderListener);
container.setInitParameter("contextInitializerClasses", "mvctest.web.DemoApplicationContextInitializer");
AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
webContext.register(MvcConfiguration.class);
DispatcherServlet dispatcherServlet = new DispatcherServlet(webContext);
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", dispatcherServlet);
dispatcher.addMapping("/");
}
}
如果它是正常的web.xml配置,则可以通过以下方式指定初始化程序:
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.myapp.spring.SpringContextProfileInit</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
因此,可以得出结论,除了Initializer后缀之外,WebApplicationInitializer和ApplicationContextInitializer都具有完全不同的目的。 Servlet容器在Web应用程序启动时使用WebApplicationInitializer并提供了一种以编程方式创建Web应用程序的方法(替换web.xml文件),而ApplicationContextInitializer提供了一个钩子,用于在完全创建Spring应用程序上下文之前对其进行配置。