서블릿 필터에서 스프링 빈을 얻으려면 어떻게 해야 합니까?
정의했습니다.javax.servlet.Filter
그리고 봄 주석이 달린 자바 수업이 있습니다.
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
@Configuration
public class SocialConfig {
// ...
@Bean
public UsersConnectionRepository usersConnectionRepository() {
// ...
}
}
나는 콩을 사고 싶습니다.UsersConnectionRepository
내 안에서Filter
그래서 저는 다음을 시도했습니다.
public void init(FilterConfig filterConfig) throws ServletException {
UsersConnectionRepository bean = (UsersConnectionRepository) filterConfig.getServletContext().getAttribute("#{connectionFactoryLocator}");
}
하지만 그것은 항상 돌아옵니다.null
어떻게 하면 봄 콩을 얻을 수 있습니까?Filter
?
세 가지 방법이 있습니다.
사용하다
WebApplicationContextUtils
:public void init(FilterConfig cfg) { ApplicationContext ctx = WebApplicationContextUtils .getRequiredWebApplicationContext(cfg.getServletContext()); this.bean = ctx.getBean(YourBeanType.class); }
- 필터를 매핑하고 필터를 빈으로 선언합니다.그런 다음 위임 프록시는 다음을 구현하는 모든 빈을 호출합니다.
Filter
인터페이스사용하다
@Configurable
필터에 있습니다.하지만 다른 두 가지 옵션 중 하나를 선호합니다. (이 옵션은 애스펙트j 직조를 사용합니다.)
시도:
UsersConnectionRepository bean =
(UsersConnectionRepository)WebApplicationContextUtils.
getRequiredWebApplicationContext(filterConfig.getServletContext()).
getBean("usersConnectionRepository");
어디에usersConnectionRepository
응용 프로그램 컨텍스트에서 빈의 이름/ID입니다.또는 더 나은 것:
UsersConnectionRepository bean = WebApplicationContextUtils.
getRequiredWebApplicationContext(filterConfig.getServletContext()).
getBean(UsersConnectionRepository.class);
또한 GenericFilterBean 및 해당 하위 클래스도 살펴봅니다.
봄에는 이것만을 위한 효용이 있습니다.
필터 코드에서 init 메서드를 다음과 같이 재정의합니다.
public void init(FilterConfig cfg) {
super.init(cfg);
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
그런 다음 다른 콩을 주입하는 것과 같은 방식으로 @당신의 콩을 필터에 주입합니다.
@Inject
private UsersConnectionRepository repository;
컨텍스트 간에 콩에 액세스할 수 있는 방법에 대한 명확한 이해
봄에는 두 가지 유형의 상황이 있습니다.
루트 컨텍스트(ContextLoaderListener에서 컨텍스트가 로드됨)
서블릿 컨텍스트(Dispatcher Servlet에 의해 로드된 컨텍스트)
rootContext에 정의된 콩이 servletContext에 표시됩니까? - 네
루트 컨텍스트에서 정의된 콩은 기본적으로 모든 서블릿 컨텍스트에서 항상 표시됩니다.예를 들어, 루트 컨텍스트에 정의된 source been은 아래와 같이 servlet 컨텍스트에서 액세스할 수 있습니다.
@Configuration
public class RootConfiguration
{
@Bean
public DataSource dataSource()
{
...
}
}
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.pvn.mvctiles")
public class ServletConfiguration implements WebMvcConfigurer
{
@Autowired
private DataSource dataSource;
...
}
servletContext에 정의된 콩은 rootContext에 표시됩니다. 예*
(예에서 *를 선택하는 이유)
컨텍스트 순서의 초기화는 rootContext 먼저이고 servletContext 다음입니다.rootContext를 초기화하는 동안, 즉 루트 컨텍스트 구성 클래스/xml에서 servletContext에 정의된 빈을 가져오려고 하면 NULL이 표시됩니다. (servletContext가 아직 초기화되지 않았기 때문에 루트 컨텍스트 초기화 중에 빈이 표시되거나 등록되지 않았다고 말할 수 있습니다.)
그러나 servletContext 초기화 후 servletContext에 정의된 콩을 얻을 수 있습니다(애플리케이션 컨텍스트를 통해 콩을 얻을 수 있습니다).
당신은 그것을 인쇄하고 확인할 수 있습니다.
applicationContext.getBeanDefinitionNames();
필터 또는 다른 서블릿 컨텍스트에서 서블릿 컨텍스트의 빈에 액세스하려면 다음을 추가합니다."org.springframework.web.servlet"
class 입니다.
@Configuration
@ComponentScan(basePackages = "org.springframework.web.servlet" )
public class RootConfiguration
한 후 콩을 수 .
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에서 사용자 정의 콩을 가져오려면 아래와 같이 rootContext 구성 요소에 기본 패키지 값을 추가합니다.
@Configuration
@ComponentScan(basePackages = { "com.your.configuration.package", "org.springframework.web.servlet" })
public class RootConfiguration
위의 지정된 구성은 주입된 종속성을 rootContext에서 사용할 수 있고 서블릿 필터에서 액세스할 수 있도록 하려면 유용합니다.를 들어 응답을 해야 합니다.HttpMessageConverter
그러나 servletContext로 구성된 경우 구성된 변환기에 액세스하여 동일한 응답을 보낼 수 있습니다.
필터에서 작동하지 아래 자동 배선은 서블릿 필터에서 하지 않습니다.
@Autowired
private ApplicationContext appContext;
스프링 컨테이너가 초기화되기 전에 필터가 초기화되므로 서블릿 필터에서 ApplicationContext 자동 배선이 작동하지 않습니다.(필터 순서와 ProxyFilter 위임 순서에 따라 다름)
필터에서 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());
}
}
그것이 문맥 사이에서 콩이 어떻게 접근될 수 있는지에 대한 명확한 아이디어를 제공하기를 바랍니다.
이 클래스 아래로 확장됩니다.
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;
}
스프링 보안을 사용하고 OncePerRequestFilter를 확장하는 경우 한 가지 솔루션 더 제공
@Component
public class CustomAuthorizationFilter extends OncePerRequestFilter{
@Autowired
ResourceConfig resourceConfig;
public CustomAuthorizationFilter() {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
...your code
... //resourceConfig will not be null
언급URL : https://stackoverflow.com/questions/7882042/how-can-i-get-a-spring-bean-in-a-servlet-filter
'programing' 카테고리의 다른 글
변수에 필요한/변수로 변환 (0) | 2023.09.04 |
---|---|
오류 "입력 장치가 TTY가 아닙니다." (0) | 2023.09.04 |
RStudio를 사용하여 MariaDB 원격 서버에 연결 (0) | 2023.09.04 |
선택한 라디오 버튼의 레이블에 대한 CSS 선택기 (0) | 2023.08.30 |
자바스크립트에서 IsPostBack을 확인하려면 어떻게 해야 합니까? (0) | 2023.08.30 |