getServletConfigClasses()
vs getRootConfigClasses()
を拡張するときの違いは何ですかAbstractAnnotationConfigDispatcherServletInitializer
。私は今朝から多くの情報源を読んでいますが、違いについてはまだ明確な理解が得られていません。
次の2つの構成をご覧ください。
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;
}
}
_
ConServlet&WebConfig(多かれ少なかれ)ビューの初期化のような同じことを行う両方を見ます:
しかし、なぜ :
getRootConfigClasses()
で返されますgetServletConfigClasses()
で返されますドキュメントを読みます
両方getRootConfigClasses()&getServletConfigClasses()は
提供する@Configurationクラスまたは@Componentクラス、あるいはその両方を指定します(それらの違い)
getRootConfigClasses()
getServletConfigClasses()
しかし、なぜConServlet&WebConfig同じこと(ビューの初期化など)を行うと、多分私はそれを誤解しているかもしれません。 単純な用語/例の実際のルートコンテキストおよびディスパッチャサーブレット(これは知っています)
ありがとうございました!
ApplicationContext
階層のビットSpringのApplicationContext
は、複数の(階層)コンテキストをロードする機能を提供し、各コンテキストがアプリケーションのWebレイヤーや中間層サービスなどの特定の1つのレイヤーに集中できるようにします。
階層ApplicationContext
を使用する標準的な例の1つは、Webアプリケーションに複数のDispatcherServlet
があり、datasources
などの一般的なBeanのいくつかを共有する場合です。それら。このようにして、すべての共通Beanを含むルートApplicationContext
と、ルートコンテキストから共通Beanを継承する複数のWebApplicationContext
sを定義できます。
Web MVCフレームワークでは、各DispatcherServlet
には独自のWebApplicationContext
があり、ルートWebApplicationContext
で既に定義されているすべてのBeanを継承します。これらの継承されたBeanは、サーブレット固有のスコープでオーバーライドできます。また、特定のServlet
インスタンスに対してローカルな新しいスコープ固有のBeanを定義できます。
Spring Web MVCの典型的なコンテキスト階層(Springドキュメント)
単一のDispatherServlet
ワールドに住んでいる場合、このシナリオのルートコンテキストを1つだけ持つこともできます。
Spring Web MVCのシングルルートコンテキスト(Springドキュメント)
Webアプリケーションを開発していて、Spring MVC、Spring Security、Spring Data JPAを使用するとします。この単純なシナリオでは、少なくとも3つの異なる構成ファイルがあります。 WebConfig
s、ViewResolver
s、Controller
sなど、Web関連のすべての構成を含むArgumentResolver
。次のようなものです。
@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
を定義して、単純な古いjsp、貧弱な人生決定を解決しています。 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
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception { ... }
@Override
protected void configure(HttpSecurity http) throws Exception { ... }
}
これらすべてを一緒に接着するには、2つのオプションがあります。まず、ルートコンテキストに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[] { "/" };
}
}
ここには単一のDispatcherServlet
があるので、WebConfig
をルートコンテキストに追加して、サーブレットコンテキストを空にすることができます。
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 を読むことができます。
ルート構成クラスは、実際には、アプリケーション固有であり、フィルターに使用できる必要があるBeanを作成するために使用されます(フィルターはサーブレットの一部ではないため)。
Servlet Configクラスは、ViewResolvers、ArgumentResolvers、InterceptorなどのDispatcherServlet固有のBeanを作成するために実際に使用されます。
ルート構成クラスが最初にロードされ、次にサーブレット構成クラスがロードされます。
ルート構成クラスは親コンテキストになり、ApplicationContext
インスタンスを作成します。 Servlet Config Classesが親コンテキストの子コンテキストであり、WebApplicationContext
インスタンスを作成する場所。
ConServlet
構成では、InternalResourceViewResolver
でのみ必要であるため、@EnableWebMvc
およびWebConfig
Beanを指定する必要はありません。