javax.servlet.Filter
を定義し、Java Springアノテーション付きのクラスがあります。
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
@Configuration
public class SocialConfig {
// ...
@Bean
public UsersConnectionRepository usersConnectionRepository() {
// ...
}
// ...
}
UsersConnectionRepository
でFilter
のBeanを取得したいので、次のことを試しました。
public void init(FilterConfig filterConfig) throws ServletException {
UsersConnectionRepository bean = (UsersConnectionRepository) filterConfig.getServletContext().getAttribute("#{connectionFactoryLocator}");
}
ただし、常にnull
を返します。 Filter
でSpring Beanを取得するにはどうすればよいですか?
試してください:
UsersConnectionRepository bean =
(UsersConnectionRepository)WebApplicationContextUtils.
getRequiredWebApplicationContext(filterConfig.getServletContext()).
getBean("usersConnectionRepository");
usersConnectionRepository
は、アプリケーションコンテキスト内のBeanの名前/ IDです。またはさらに良い:
UsersConnectionRepository bean = WebApplicationContextUtils.
getRequiredWebApplicationContext(filterConfig.getServletContext()).
getBean(UsersConnectionRepository.class);
GenericFilterBean とそのサブクラスもご覧ください。
3つの方法があります。
WebApplicationContextUtils
を使用:
public void init(FilterConfig cfg) {
ApplicationContext ctx = WebApplicationContextUtils
.getRequiredWebApplicationContext(cfg.getServletContext());
this.bean = ctx.getBean(YourBeanType.class);
}
DelegatingFilterProxy
を使用して、そのフィルターをマップし、フィルターをBeanとして宣言します。その後、委任プロキシは、Filter
インターフェイスを実装するすべてのBeanを呼び出します。
使用する @Configurable
フィルター。ただし、他の2つのオプションのいずれかを選択します。 (このオプションはaspectjウィービングを使用します)
Springにはこのためのユーティリティがあります。
フィルターコードで、次のようにinitメソッドをオーバーライドします。
public void init(FilterConfig cfg) {
super.init(cfg);
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
次に、注入する他のBeanと同じ方法で、Beanをそのフィルターに@Injectします。
@Inject
private UsersConnectionRepository repository;
これをクラスの下に拡張します。
abstract public class SpringServletFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//must provide autowiring support to inject SpringBean
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, filterConfig.getServletContext());
}
@Override
public void destroy() { }
abstract public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException;
}
春には2種類のコンテキストがあります
1。ルートコンテキスト(ApplicationContext)
2。サーブレットコンテキスト(WebApplicationContext)
ルートコンテキストで定義されたBeanは、デフォルトですべてのサーブレットコンテキストで常に表示されます。たとえば、ルートコンテキストで定義されたdataSource Beanは、以下に示すようにサーブレットコンテキストでアクセスできます。
@Configuration
public class RootConfiguration
{
@Bean
public DataSource dataSource()
{
...
}
}
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.pvn.mvctiles")
public class ServletConfiguration implements WebMvcConfigurer
{
@Autowired
private DataSource dataSource;
...
}
(なぜ*はい)
1。コンテキストの順序の初期化は、最初にrootContextであり、次にservletContextです。 rootContextの初期化中、つまり、ルートコンテキスト設定クラス/ xmlで、servletContextで定義されたBeanを取得しようとすると、NULLが取得されます。 (servletContextはまだ初期化されていないため、rootContextの初期化中にBeanが表示/登録されていないと言うことができます)
ただし、servletContextの初期化後にservletContextで定義されたBeanを取得できます(アプリケーションコンテキストからBeanを取得できます)
印刷して確認できます
applicationContext.getBeanDefinitionNames();
2。フィルタまたは別のサーブレットコンテキストでサーブレットコンテキストのBeanにアクセスする場合は、"org.springframework.web.servlet"
ルート設定クラス/ xmlへのベースパッケージ
@Configuration
@ComponentScan(basePackages = "org.springframework.web.servlet" )
public class RootConfiguration
追加すると、アプリケーションコンテキストから以下のすべてのBeanを取得できます
springSecurityConfig
、tilesConfigurer
、themeSource
、themeResolver
、messageSource
、localeResolver
、requestMappingHandlerMapping
、mvcPathMatcher
、mvcUrlPathHelper
、mvcContentNegotiationManager
、viewControllerHandlerMapping
、beanNameHandlerMapping
、resourceHandlerMapping
、mvcResourceUrlProvider
、defaultServletHandlerMapping
、requestMappingHandlerAdapter
、mvcConversionService
、mvcValidator
、mvcUriComponentsContributor
、httpRequestHandlerAdapter
、simpleControllerHandlerAdapter
、handlerExceptionResolver
、mvcViewResolver
、mvcHandlerMappingIntrospector
RootContextからカスタムBeanを取得する場合は、以下に示すようにrootContextコンポーネントスキャンにベースパッケージ値を追加します。
@Configuration
@ComponentScan(basePackages = { "com.your.configuration.package", "org.springframework.web.servlet" })
public class RootConfiguration
上記の設定は、注入された依存関係をrootContextで使用可能にし、サーブレットフィルターでアクセスできるようにする場合に役立ちます。たとえば、フィルターで例外をキャッチし、HttpMessageConverter
によって送信された応答と同じエラー応答を送信するが、servletContextで構成されている場合、その構成されたコンバーターにアクセスして同じ応答を送信できます。
このことに注意してください、自動配線はサーブレットフィルターでは機能しません
@Autowired
private ApplicationContext appContext;
SpringContextが初期化される前にフィルターが初期化されるため、ApplicationContext自動配線はサーブレットフィルターでは機能しません。(フィルターとDelegatingProxyFilterの順序に依存します)
したがって、フィルターでapplicationContextを取得するには
public class YourFilter implements Filter
{
private ApplicationContext appContext;
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
Filter.super.init(filterConfig);
appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext());
}
}
コンテキスト間でBeanにアクセスする方法について明確なアイデアが得られることを願っています。