java 扩展 AbstractAnnotationConfigDispatcherServletInitializer 时的 getServletConfigClasses() 与 getRootConfigClasses()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35258758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
getServletConfigClasses() vs getRootConfigClasses() when extending AbstractAnnotationConfigDispatcherServletInitializer
提问by Plain_Dude_Sleeping_Alone
What is the difference between getServletConfigClasses()
vs getRootConfigClasses()
when extending AbstractAnnotationConfigDispatcherServletInitializer
.
I've been reading a lot sources since this morning but I haven't get any clear understanding on the differences yet :
扩展时getServletConfigClasses()
vs 之间有什么区别。从今天早上开始,我一直在阅读很多资料,但我还没有对差异有任何明确的了解:getRootConfigClasses()
AbstractAnnotationConfigDispatcherServletInitializer
Please have look at these two configurations :
请看一下这两个配置:
1).
1)。
public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { ConServlet.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
....
....
}
The ConServlet.class
is refering to
指的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).
2)。
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
.....
}
the WebConfig.classis refering to
该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;
}
}
I see both ConServlet& WebConfig(more or less) doing the same things like initializating view :
我看到ConServlet和WebConfig(或多或少)都在做同样的事情,比如初始化视图:
But why :
但为什么 :
- ConServletis returned in
getRootConfigClasses()
- while WebConfigis returned in
getServletConfigClasses()
- ConServlet被返回
getRootConfigClasses()
- 而WebConfig返回
getServletConfigClasses()
I read the documentation
我阅读了文档
both getRootConfigClasses()& getServletConfigClasses()is for
既getRootConfigClasses() &getServletConfigClasses()是用于
Specify @Configuration and/or @Component classes to be provided to.. (their differences )
指定要提供给..的@Configuration 和/或@Component 类(它们的区别)
- the root application contextfor
getRootConfigClasses()
- the dispatcher servlet application context for
getServletConfigClasses()
- 根应用上下文为
getRootConfigClasses()
- 调度程序 servlet 应用程序上下文
getServletConfigClasses()
but why then ConServlet& WebConfigdoing same things (like initizialising view), maybe I'm the one misunderstood it. What's are actually root context and dispatcher servlets (I know this one) in the simple term/example
但是为什么ConServlet和WebConfig做同样的事情(比如初始化视图),也许我是误解了它。在简单的术语/示例中,什么实际上是根上下文和调度程序 servlet(我知道这个)
Thank you!
谢谢!
回答by Ali Dehghani
A Bit on ApplicationContext
Hierarchies
关于ApplicationContext
层次结构的一点
Spring's ApplicationContext
provides the capability of loading multiple (hierarchical) contexts, allowing each to be focused on one particular layer, such as the web layer of an application or middle-tier services.
SpringApplicationContext
提供了加载多个(分层)上下文的能力,允许每个上下文专注于一个特定的层,例如应用程序的 web 层或中间层服务。
One of the canonical examples of using hierarchical ApplicationContext
is when we have multiple DispatcherServlet
s in a web application and we're going to share some of the common beans such as datasources
between them. This way, we can define a root ApplicationContext
that contain all the common beans and multiple WebApplicationContext
s that inherit the common beans from the root context.
使用层次结构的典型示例之一ApplicationContext
是当我们DispatcherServlet
在 Web 应用程序中有多个s 并且我们将datasources
在它们之间共享一些公共 bean 时。这样,我们可以定义一个ApplicationContext
包含所有公共 bean的根和多个WebApplicationContext
从根上下文继承公共 bean 的 s。
In the Web MVC framework, each DispatcherServlet
has its own WebApplicationContext
, which inherits all the beans already defined in the root WebApplicationContext
. These inherited beans can be overridden in the servlet-specific scope, and you can define new scope-specific beans local to a given Servlet
instance.
在 Web MVC 框架中,每个DispatcherServlet
都有自己的WebApplicationContext
,它继承了根中已经定义的所有 bean WebApplicationContext
。这些继承的 bean 可以在 servlet 特定的范围内被覆盖,并且您可以定义新的特定于给定Servlet
实例的范围特定的 bean 。
Typical context hierarchy in Spring Web MVC (Spring Documentation)
Spring Web MVC 中的典型上下文层次结构(Spring 文档)
If you're living in a single DispatherServlet
world, it is also possible to have just one root context for this scenario:
如果您生活在一个单一的DispatherServlet
世界中,对于这种情况,也可能只有一个根上下文:
Single root context in Spring Web MVC (Spring Documentation)
Spring Web MVC 中的单根上下文(Spring 文档)
Talk is cheap, Show me the code!
说话很便宜,给我看代码!
Suppose we're developing a web application and we're going to use Spring MVC, Spring Security and Spring Data JPA. For this simple scenario, we would have at least three different config files. A WebConfig
that contains all our web related configurations, such as ViewResolver
s, Controller
s, ArgumentResolver
s, etc. Something like following:
假设我们正在开发一个 Web 应用程序,我们将使用 Spring MVC、Spring Security 和 Spring Data JPA。对于这个简单的场景,我们至少有三个不同的配置文件。AWebConfig
包含我们所有与 Web 相关的配置,例如ViewResolver
s、Controller
s、ArgumentResolver
s 等。类似于以下内容:
@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);
}
}
Here I'm defining a ViewResolver
to resolve my plain old jsps, poor life decisions, basically. We would need a RepositoryConfig
, which contains all the data access facilities such as DataSource
, EntityManagerFactory
, TransactionManager
, etc. It probably would be like following:
在这里,我定义了一个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
which contains all the security related stuff!
还有一个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 { ... }
}
For gluing all these together, we have two options. First, we can define a typical hierarchical ApplicationContext
, by adding RepositoryConfig
and SecurityConfig
in root context and WebConfig
in their child context:
为了将所有这些粘合在一起,我们有两种选择。首先,我们可以ApplicationContext
通过在根上下文及其子上下文中添加RepositoryConfig
和来定义典型的分层结构: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[] { "/" };
}
}
Since we have a single DispatcherServlet
here, we can add the WebConfig
to the root context and make the servlet context empty:
由于我们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
进一步阅读
Skaffman did a great job on explaining ApplicationContext
hierarchies in this answer, which is highly recommended. Also, you can read Spring Documentation.
SkaffmanApplicationContext
在这个答案中解释层次结构做得很好,强烈推荐。此外,您可以阅读Spring 文档。
回答by shazin
Root Config Classes are actually used to Create Beans which are Application Specific and which needs to be available for Filters (As Filters are not part of Servlet).
根配置类实际上用于创建特定于应用程序的 Bean,这些 Bean 需要可用于过滤器(因为过滤器不是 Servlet 的一部分)。
Servlet Config Classes are actually used to Create Beans which are DispatcherServlet specific such as ViewResolvers, ArgumentResolvers, Interceptor, etc.
Servlet 配置类实际上用于创建特定于 DispatcherServlet 的 Bean,例如 ViewResolvers、ArgumentResolvers、Interceptor 等。
Root Config Classes will be loaded first and then Servlet Config Classes will be loaded.
将首先加载根配置类,然后加载 Servlet 配置类。
Root Config Classes will be the Parent Context and it will create a ApplicationContext
instace. Where as Servlet Config Classes will be the Child Context of the Parent Context and it will create a WebApplicationContext
instance.
根配置类将是父上下文,它将创建一个ApplicationContext
实例。其中 Servlet 配置类将是父上下文的子上下文,它将创建一个WebApplicationContext
实例。
In your ConServlet
Configuration, You don't need to specify the @EnableWebMvc
as well the InternalResourceViewResolver
bean as they are only required at the WebConfig
.
在你的ConServlet
配置,你并不需要指定@EnableWebMvc
为好InternalResourceViewResolver
,因为它们是在只需豆WebConfig
。