서블릿 필터에서 스프링 빈을 얻으려면 어떻게 해야 합니까?
정의했습니다.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 |