![](/img/trans.png)
[英]How can I run servlet-filter of a different project in my project without spring @Component or @Bean annotation
[英]How can I get a Spring bean in a servlet filter?
我已經定義了一個javax.servlet.Filter
並且我有帶有 Spring 注釋的 Java 類。
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
@Configuration
public class SocialConfig {
// ...
@Bean
public UsersConnectionRepository usersConnectionRepository() {
// ...
}
}
我想在我的Filter
獲取 bean UsersConnectionRepository
,所以我嘗試了以下操作:
public void init(FilterConfig filterConfig) throws ServletException {
UsersConnectionRepository bean = (UsersConnectionRepository) filterConfig.getServletContext().getAttribute("#{connectionFactoryLocator}");
}
但它總是返回null
。 如何在Filter
獲取 Spring bean?
有三種方式:
使用WebApplicationContextUtils
:
public void init(FilterConfig cfg) { ApplicationContext ctx = WebApplicationContextUtils .getRequiredWebApplicationContext(cfg.getServletContext()); this.bean = ctx.getBean(YourBeanType.class); }
使用DelegatingFilterProxy
- 映射該過濾器,並將過濾器聲明為bean。 然后,委派代理將調用實現Filter
接口的所有bean。
在過濾器上使用@Configurable
。 我更喜歡其他兩個選項中的一個。 (此選項使用aspectj編織)
嘗試:
UsersConnectionRepository bean =
(UsersConnectionRepository)WebApplicationContextUtils.
getRequiredWebApplicationContext(filterConfig.getServletContext()).
getBean("usersConnectionRepository");
其中usersConnectionRepository
是應用程序上下文中bean的名稱/ id。 甚至更好:
UsersConnectionRepository bean = WebApplicationContextUtils.
getRequiredWebApplicationContext(filterConfig.getServletContext()).
getBean(UsersConnectionRepository.class);
還可以查看GenericFilterBean及其子類。
Spring有一個實用工具。
在您的Filter代碼中,覆蓋init方法,如下所示:
public void init(FilterConfig cfg) {
super.init(cfg);
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
然后你只需將bean注入該過濾器,就像你注入的任何其他bean一樣。
@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;
}
春天有兩種類型的背景
1.根上下文(ApplicationContext)
2. Servlet上下文(WebApplicationContext)
默認情況下,根上下文中定義的Bean始終在所有servlet上下文中可見。 例如,可以在servlet上下文中訪問根上下文中定義的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尚未初始化,因此我們可以說bean在初始化rootContext期間不可見/注冊)
但是在初始化servletContext之后你可以在servletContext中定義bean(你可以通過應用程序上下文獲取bean)
你可以打印並確認
applicationContext.getBeanDefinitionNames();
2.如果要在過濾器或另一個servlet上下文中訪問servlet上下文的bean,請將"org.springframework.web.servlet"
基本包添加到root配置類/ 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中提供注入依賴項,並且可以在servlet-filter中訪問,則上面給出的配置將非常有用。 例如,如果您在過濾器中捕獲異常並希望發送錯誤響應,該響應與HttpMessageConverter
發送的響應相同,但它是在servletContext中配置的,那么您可能希望訪問該配置的轉換器以發送相同的響應。
請注意,下面的自動裝配在servlet過濾器中不起作用
@Autowired
private ApplicationContext appContext;
ApplicationContext自動裝配在servlet過濾器中不起作用,因為過濾器在spring容器初始化之前被初始化。(取決於你的過濾器和DelegatingProxyFilter的順序)
因此,要在filter中獲取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。
如果您使用彈簧安全性並擴展 OncePerRequestFilter,則另一種解決方案
@Component
public class CustomAuthorizationFilter extends OncePerRequestFilter{
@Autowired
ResourceConfig resourceConfig;
public CustomAuthorizationFilter() {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
...your code
... //resourceConfig will not be null
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.