Как я могу получить bean-компонент Spring в фильтре сервлета?

Я определил 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 в фильтре ?

40
задан Andrew Regan 27 September 2019 в 09:47
поделиться

1 ответ

Чтобы иметь четкое представление о том, как к бобам можно получить доступ между контекстами

, существует два типа контекста пружиной
1. Корневой контекст (ApplicationContext)
2. Контекст сервлета (WebApplicationContext)

Является бобами, определенными в rootContext, видимы в servletContext? - ДА

Бобы, определенные в корневом контексте, всегда видимо во всех контекстах сервлета по умолчанию. например, к бобу источника данных, определенному в корневом контексте, можно получить доступ в контексте сервлета, как дали ниже.

@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 - да*

(Почему * в Да)
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, он дает четкое представление о том, как к бобам можно получить доступ между контекстами.

1
ответ дан 27 November 2019 в 01:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: