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

2024-03-21

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

请看一下这两个配置:

1).

public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

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

The 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 }; 
    }
    .....
}

the 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;
    }
}

我都看到了ConServlet & 网页配置(或多或少)做同样的事情,比如初始化视图:

但为什么 :

  • ConServlet返回于getRootConfigClasses()
  • while 网页配置返回于getServletConfigClasses()

我阅读了文档

both 获取根配置类() & getServletConfigClasses() is for

指定要提供给..的@Configuration和/或@Component类。 (他们的区别)

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

但为什么那么ConServlet & 网页配置做同样的事情(比如初始化视图),也许我是误解它的人。实际上是根上下文和调度程序 servlet(我知道这个)简单术语/示例

谢谢你!


A Bit on ApplicationContext Hierarchies

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

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

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

Typical context hierarchy in Spring Web MVC
Typical context hierarchy in Spring Web MVC (Spring Documentation)

如果你住在单身公寓DispatherServletworld,对于这种情况也可能只有一个根上下文:

enter image description here
Single root context in Spring Web MVC (Spring Documentation)

Talk is cheap, Show me the code!

假设我们正在开发一个 Web 应用程序,并且将使用 Spring MVC、Spring Security 和 Spring Data JPA。对于这个简单的场景,我们至少有三个不同的配置文件。 AWebConfig其中包含我们所有与网络相关的配置,例如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,其中包含所有数据访问设施,例如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() { ... }
}

And a 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, 通过增加RepositoryConfig and SecurityConfig在根上下文中和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[] { "/" };
    }
}

Further Reading

斯卡夫曼在解释方面做得很好ApplicationContext此中的层次结构answer https://stackoverflow.com/a/5132637/1393484,强烈推荐。另外,您还可以阅读Spring文档 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-servlet.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

扩展 AbstractAnnotationConfigDispatcherServletInitializer 时的 getServletConfigClasses() 与 getRootConfigClasses() 的相关文章

随机推荐