getServletConfigClasses () vs getRootConfigClasses () lors de l'extension AbstractAnnotationConfigDispatcherservletinitializer
Quelle est la différence entre getServletConfigClasses()
et getRootConfigClasses()
lors de l'extension AbstractAnnotationConfigDispatcherServletInitializer
.
J'ai lu beaucoup de sources depuis ce matin mais je n'ai pas encore compris clairement les différences:
s'il vous Plaît un coup d'oeil à ces deux configurations :
1).
public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { ConServlet.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
....
....
}
ConServlet.class
fait référence à
@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 };
}
.....
}
la WebConfig.classe fait référence à
@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;
}
}
je vois deux ConServlet& WebConfig (plus ou moins) faisant les mêmes choses comme la vue initialisante:
Mais pourquoi :
- ConServlet est retourné dans
getRootConfigClasses()
- WebConfig est retourné dans
getServletConfigClasses()
j'ai lu la documentation
getRootConfigClasses ()& getServletConfigClasses ()
Spécifier @Configuration et / ou @classes de composants à fournir.. (leurs différences )
- le contexte de l'application racine
getRootConfigClasses()
- le répartiteur servlet contexte de l'application pour
getServletConfigClasses()
mais pourquoi alors ConServlet& WebConfig faire les mêmes choses (comme initialiser la vue), peut-être que c'est moi qui l'ai mal compris. Ce qui est en fait le contexte racine et les servlets de répartiteur (je connais celui-ci) dans le terme simple/exemple
Merci!
2 réponses
un peu sur ApplicationContext
Hiérarchies
Ressort ApplicationContext
fournit la possibilité de charger plusieurs contextes (hiérarchiques), permettant à chacun d'être concentré sur une couche particulière, telle que la couche web d'une application ou des services de niveau intermédiaire.
un des exemples canoniques d'utilisation de ApplicationContext
c'est quand nous avons plusieurs DispatcherServlet
s dans une application web et nous allons partager certains des haricots communs tels que datasources
entre eux. De cette façon, nous pouvons définir une racine ApplicationContext
qui contiennent tous les haricots communs et plusieurs WebApplicationContext
s qui héritent les haricots communs du contexte de la racine.
Dans le Web framework MVC, chaque DispatcherServlet
a son propre WebApplicationContext
, qui hérite de tous les grains déjà définis dans la racine WebApplicationContext
. Ces fèves héritées peuvent être supplantées dans la portée spécifique à une portion, et vous pouvez définir de nouvelles fèves spécifiques à une portion donnéeServlet
instance.
Typique contexte de hiérarchie dans Web Spring MVC (Printemps Documentation)
si vous vivez seul DispatherServlet
monde, il est également possible d'avoir un seul contexte de la racine pour ce scénario:
contexte de racine simple dans le Web de printemps MVC (printemps La Documentation)
parler c'est pas cher, Montrez-moi le code!
supposons que nous développions une application web et que nous utilisions Spring MVC, Spring Security et Spring Data JPA. Pour ce scénario simple, nous aurions au moins trois fichiers de configuration différents. WebConfig
qui contient toutes nos configurations liées au web, comme ViewResolver
s,Controller
s,ArgumentResolver
s, etc. Quelque chose comme suit:
@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);
}
}
Ici je suis la définition d'un ViewResolver
pour résoudre mes vieux jsps, de mauvaises décisions de vie, en gros. Nous aurions besoin d'un RepositoryConfig
, qui contient toutes les facilités d'accès aux données telles que DataSource
,EntityManagerFactory
,TransactionManager
, etc. Il serait sans doute comme suit:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.so.repository")
public class RepositoryConfig {
@Bean
public DataSource dataSource() { ... }
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { ... }
@Bean
public PlatformTransactionManager transactionManager() { ... }
}
Et SecurityConfig
qui contient tous les trucs liés à la sécurité!
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception { ... }
@Override
protected void configure(HttpSecurity http) throws Exception { ... }
}
pour coller tout cela ensemble, nous avons deux options. Tout d'abord, on peut définir une typique hiérarchique ApplicationContext
, en ajoutant RepositoryConfig
et SecurityConfig
dans le contexte de la racine et WebConfig
dans le contexte de leur enfant:
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[] { "/" };
}
}
Depuis que nous avons un seul DispatcherServlet
ici, on peut ajouter le WebConfig
au contexte root et vider le contexte 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[] { "/" };
}
}
Autres Lectures
Skaffman a fait du bon travail en expliquant ApplicationContext
hiérarchies dans ce réponse, ce qui est fortement recommandé. Aussi, vous pouvez lire Documentation De Printemps.
les Classes de configuration racine sont en fait utilisées pour créer des fèves qui sont spécifiques à L'Application et qui doivent être disponibles pour les filtres (car les filtres ne font pas partie de Servlet).
les Classes de configuration des servlets sont en fait utilisées pour créer des fèves qui sont spécifiques aux répartiteurs comme ViewResolvers, ArgumentResolvers, Interceptor, etc.
les Classes de configuration racine seront chargées en premier et les classes de configuration Servlet seront ensuite chargées.
les Classes de configuration racine vont être le Parent Contexte et il va créer un ApplicationContext
instace. Où as Servlet Config Classes sera le contexte enfant du contexte Parent et créera un WebApplicationContext
instance.
Dans votre ConServlet
Configuration, vous n'avez pas besoin de spécifier le @EnableWebMvc
dans le InternalResourceViewResolver
bean comme ils ne sont tenus à l' WebConfig
.