A Bit on ApplicationContext Hierarchies
Spring
ApplicationContext提供了加载多个(分层)上下文的功能,允许每个上下文集中在一个特定的层上,例如应用程序的Web层或中间层服务。
使用分层的一个典型示例
ApplicationContext是,当我们
DispatcherServlet在Web应用程序中有多个s时,我们将共享
datasources它们之间的一些常见bean 。这样,我们可以定义一个
ApplicationContext包含所有通用bean 的根,以及多个
WebApplicationContext从根上下文继承通用bean的s。
在Web MVC框架中,每个框架
DispatcherServlet都有自己的框架,该框架
WebApplicationContext继承了root中已经定义的所有bean
WebApplicationContext。这些继承的bean可以在servlet特定的作用域中被覆盖,并且你可以在给定Servlet实例本地定义新的特定于作用域的bean 。
Spring Web MVC中的典型上下文层次结构(Spring documentation)
如果你生活在一个单一的
DispatherServlet世界中,则在这种情况下也可能只有一个根上下文:
Spring Web MVC中的单根上下文(Spring documentation)
Talk is cheap, Show me the pre!
假设我们正在开发一个Web应用程序,并且将使用Spring MVC,Spring Security和Spring Data JPA。对于这种简单的情况,我们将至少具有三个不同的配置文件。一个WebConfig包含了所有我们的网络相关的配置,如
ViewResolverS,ControllerS,ArgumentResolverS,等喜欢的东西如下:
@EnableWebMvc@Configuration@ComponentScan(basePackages = "com.so.web")public class WebConfig extends WebMvcConfigurerAdapter { @Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } @Override public void configurePathMatch(PathMatchConfigurer configurer) { final boolean DO_NOT_USE_SUFFIX_PATTERN_MATCHING = false; configurer.setUseSuffixPatternMatch(DO_NOT_USE_SUFFIX_PATTERN_MATCHING); }}在这里,我定义一个a
ViewResolver来基本上解决我的普通旧jsps,糟糕的生活决策。我们需要一个RepositoryConfig,它包含了所有的数据访问设施,如
DataSource,EntityManagerFactory,TransactionManager,等它可能会像下面:
@Configuration@EnableTransactionManagement@EnableJpaRepositories(basePackages = "com.so.repository")public class RepositoryConfig { @Bean public DataSource dataSource() { ... } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { ... } @Bean public PlatformTransactionManager transactionManager() { ... }}并且
SecurityConfig其中包含所有与安全相关的内容!
@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter { @Override @Autowired protected void configure(AuthenticationManagerBuilder auth) throws Exception { ... } @Override protected void configure(HttpSecurity http) throws Exception { ... }}为了将所有这些粘合在一起,我们有两个选择。首先,我们可以
ApplicationContext通过在根上下文及其子上下文中添加
RepositoryConfig和来定义典型的分层结构:
SecurityConfigWebConfig
public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] { RepositoryConfig.class, SecurityConfig.class }; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { WebConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; }}由于
DispatcherServlet这里只有一个,因此我们可以将添加
WebConfig到根上下文中,并使servlet上下文为空:
public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] { RepositoryConfig.class, SecurityConfig.class, WebConfig.class }; } @Override protected Class<?>[] getServletConfigClasses() { return null; } @Override protected String[] getServletMappings() { return new String[] { "/" }; }}


