gpt4 book ai didi

java - 扩展 AbstractAnnotationConfigDispatcherServletInitializer 时的 getServletConfigClasses() 与 getRootConfigClasses()

转载 作者:IT老高 更新时间:2023-10-28 13:02:49 24 4
gpt4 key购买 nike

getServletConfigClasses()getRootConfigClasses() 有什么区别AbstractAnnotationConfigDispatcherServletInitializer。从今天早上开始,我已经阅读了很多资料,但我还没有对差异有任何清楚的了解:

请看看这两个配置:

1).

public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

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

ConServlet.class指的是

@EnableWebMvc 
@Configuration
@ComponentScan({ "com" })
@Import({ SecurityConfig.class })
public class ConServlet {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/pages/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}

2)。

public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}

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

WebConfig.class 指的是

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "....." })
public class WebConfig extends WebMvcConfigurerAdapter {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}

@Bean
public ViewResolver viewResolver() {

InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}

我看到 ConServletWebConfig(或多或少)都在做同样的事情,比如初始化 View :

但是为什么:

  • ConServletgetRootConfigClasses()
  • 中返回
  • WebConfiggetServletConfigClasses() 中返回

我阅读了文档

getRootConfigClasses() & getServletConfigClasses() 都是为了

Specify @Configuration and/or @Component classes to be provided to.. (their differences )

    getRootConfigClasses()
  • 根应用程序上下文
  • getServletConfigClasses()
  • 的调度程序 servlet 应用程序上下文

但是为什么然后 ConServletWebConfig 做同样的事情(比如初始化 View ),也许是我误解了它。 简单术语/示例

中实际上是根上下文和调度程序 servlet(我知道这个)

谢谢!

最佳答案

ApplicationContext 层次结构

Spring 的 ApplicationContext 提供了加载多个(分层)上下文的能力,允许每个上下文专注于一个特定的层,例如应用程序的 Web 层或中间层服务。

使用分层 ApplicationContext 的典型示例之一是当我们在 Web 应用程序中有多个 DispatcherServlet 时,我们将共享一些常见的 bean,例如作为它们之间的 datasources。这样,我们可以定义一个根 ApplicationContext 包含所有公共(public) bean 和多个从根上下文继承公共(public) bean 的 WebApplicationContext

在Web MVC 框架中,每个DispatcherServlet 都有自己的WebApplicationContext,它继承了根WebApplicationContext 中已经定义的所有bean。这些继承的 bean 可以在特定于 servlet 的范围内被覆盖,并且您可以在给定的 Servlet 实例本地定义新的特定于范围的 bean。

Typical context hierarchy in Spring Web MVC
Spring Web MVC(Spring 文档)中的典型上下文层次结构

如果您生活在一个单一的 DispatherServlet 世界中,那么这种场景也可能只有一个根上下文:

enter image description here
Spring Web MVC 中的单一根上下文(Spring 文档)

说话很便宜,给我看代码!

假设我们正在开发一个 Web 应用程序,并且我们将使用 Spring MVC、Spring Security 和 Spring Data JPA。对于这个简单的场景,我们至少有三个不同的配置文件。一个WebConfig,包含我们所有的web相关配置,例如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);
}
}

在这里,我定义了一个 ViewResolver 来解决我简单的旧 jsps,基本上是糟糕的生活决策。我们需要一个 RepositoryConfig,其中包含所有数据访问工具,例如 DataSourceEntityManagerFactoryTransactionManager 等. 大概是这样的:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.so.repository")
public class RepositoryConfig {
@Bean
public DataSource dataSource() { ... }

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { ... }

@Bean
public PlatformTransactionManager transactionManager() { ... }
}

还有一个 SecurityConfig,其中包含所有与安全相关的内容!

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception { ... }

@Override
protected void configure(HttpSecurity http) throws Exception { ... }
}

为了将所有这些粘合在一起,我们有两种选择。首先,我们可以定义一个典型的分层ApplicationContext,在根上下文中添加RepositoryConfigSecurityConfig,在它们的中添加WebConfig子上下文:

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[] { "/" };
}
}

延伸阅读

Skaffman 在此 answer 中解释了 ApplicationContext 层次结构做得很好,强烈推荐。另外,您可以阅读 Spring Documentation .

关于java - 扩展 AbstractAnnotationConfigDispatcherServletInitializer 时的 getServletConfigClasses() 与 getRootConfigClasses(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35258758/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com