Я определил 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
в моем фильтре
, поэтому я попробовал следующее:
public void init(FilterConfig filterConfig) throws ServletException {
UsersConnectionRepository bean = (UsersConnectionRepository) filterConfig.getServletContext().getAttribute("#{connectionFactoryLocator}");
}
Но он всегда возвращает null
. Как получить компонент Spring в фильтре
?
, существует два типа контекста пружиной
1. Корневой контекст (ApplicationContext)
2. Контекст сервлета (WebApplicationContext)
Бобы, определенные в корневом контексте, всегда видимо во всех контекстах сервлета по умолчанию. например, к бобу источника данных, определенному в корневом контексте, можно получить доступ в контексте сервлета, как дали ниже.
@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 т.е., в корневой конфигурации контекста class/xml, при попытке определить боб в servletContext, Вы станете ПУСТЫМИ. (потому что servletContext еще не инициализируется, следовательно мы можем сказать, что бобы, не видимые/зарегистрированные во время инициализации rootContext)
, Но можно было определить бобы в servletContext после инициализации servletContext (можно получить бобы через контекст приложения)
, можно распечатать и подтвердить это [1 146]
applicationContext.getBeanDefinitionNames();
2. Если Вы хотите получить доступ к бобам контекста сервлета в фильтре или в другом контексте сервлета, добавьте "org.springframework.web.servlet"
основной пакет к своему корневому class/xml
@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 и сможете быть получены доступ в Вашем фильтре сервлета. Например, Если Вы ловите исключение в фильтре и хотите отправить ошибочный ответ, который является тем же как ответ, отправленный [1 131], но это настроено в servletContext, затем можно хотеть получить доступ, который настроил преобразователь для отправки того же ответа.
Примечание это, ниже автопроводного соединения не будет работать в фильтрах сервлета
@Autowired
private ApplicationContext appContext;
, автопроводное соединение 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());
}
}
Hope, он дает четкое представление о том, как к бобам можно получить доступ между контекстами.