Объявление Spring Bean в родительском контексте и дочернем контексте

У меня есть объект Spring bean (dao), который я создаю в моем ServletContext через следующий xml:


    

Этот bean объявлен внутри моего сервлета webapp. xml и используется моим приложением в ServletContext.

Я также использую SpringSecurity. Насколько я понимаю, это выполняется в другом контексте (SecurityContext).

В моем приложении есть файл webapp-security.xml, где Я создаю экземпляр настраиваемого поставщика аутентификации. Я хотел бы использовать свой dao, который используется в моем приложении, чтобы также выполнять поиск пользователей в моем контексте безопасности, но когда я запускаю:


    

я получаю сообщение об отсутствии такого bean-компонента » userDao ". Компонент автоматически подключается к bean-компонентам, объявленным в другом моем контексте, но не внутри моего контекста безопасности. Согласно Spring Docs, я не верю В web.xml


    org.springframework.web.context.ContextLoaderListener
    



    
        org.springframework.security.web.session.HttpSessionEventPublisher
    

необходимы оба отдельных контекста. Итак, мой вопрос: как мне получить доступ к моему DAO, который находится в моем ServletContext внутри моего SecurityContext? Есть ли модификатор области действия для моего dao, или я могу каким-то образом получить ServletContext во время выполнения в моем провайдере аутентификации? Для справки, вот как я хочу использовать его внутри своего провайдера аутентификации:

public class UserAuthenticationProvider extends
    AbstractUserDetailsAuthenticationProvider {

    @Override
protected UserDetails retrieveUser(String userName,
        UsernamePasswordAuthenticationToken authenticationToken)
        throws AuthenticationException {

    // use dao here

спасибо за объяснение мне

ОБНОВЛЕНИЕ:

Продолжая мое расследование, кажется, что DispatcherServlet, в котором я использую свой daos, является дочерний контекст, а контекст безопасности где-то выше.Следовательно, bean-компоненты в моем DispatcherServlet не могут быть просмотрены родительскими контекстами. Я думаю, что ответ состоит в том, чтобы как-то переместить мои объявления bean в контекст родительского приложения, но я не уверен, как это сделать. Вот мой web.xml


    contextConfigLocation
    WEB-INF/spring-*.xml
    



    
        org.springframework.security.web.session.HttpSessionEventPublisher
    



    org.springframework.web.context.ContextLoaderListener
    



    springSecurityFilterChain
    org.springframework.web.filter.DelegatingFilterProxy
    



    springSecurityFilterChain
    /*



    myapp
    org.springframework.web.servlet.DispatcherServlet
    
    1
    
        listings
        true
    


    ...

. Я переместил все свое создание dao в spring-dao.xml, а в моем spring-security.xml я теперь делаю:


daos stil остается видимым для DispatcherServlet контекст и невидимый для моего SecurityContext.

ОТВЕТИЛ:

Хорошо, я разобрался. Вот несколько полезных ссылок:

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#context-create

http: // forum .springsource.org / showthread.php? 115774-Spring-Security-Custom-UserDetailsService-to-use-User-Service-Dao

http://static.springsource.org/spring-security/site/faq.html # faq-method-security-in-web-context

Итак, проблема заключалась в том, что нам нужно было убедиться, что дао существует в ApplicationContext (верхний весенний контейнер). Чтобы убедиться, что это произошло, я изменил свой web.xml на:


    contextConfigLocation
    WEB-INF/spring-dao.xml WEB-INF/spring-security.xml
    



    org.springframework.web.context.ContextLoaderListener
    



    
        org.springframework.security.web.session.HttpSessionEventPublisher
    



    springSecurityFilterChain
    org.springframework.web.filter.DelegatingFilterProxy
    



    springSecurityFilterChain
    /*



    webapp
    org.springframework.web.servlet.DispatcherServlet
    
    1
    
        listings
        true
    

Я думал, что это гарантирует, что первый загрузчик контекста, который запускается, прочитает мою конфигурацию dao (и создаст мои bean-компоненты dao), а затем мою конфигурацию безопасности. Поскольку компоненты dao создаются таким образом, я удалил предыдущий оператор import resource = "spring-dao.xml" "в security.xml, потому что он больше не понадобится.

Сразу после настройки параметров контекста я создал ContextLoaderListener.Это контейнер Spring более высокого уровня, чем DispatcherServlet, поэтому я решил, что если он будет первым, он будет первым, кто прочитает эти файлы конфигурации, а затем он создаст bean-компоненты. Тогда любой дочерний контекст получит к ним доступ. Это может быть не так, как это работает, поскольку DispatcherServlet может даже не читать contextConfigLocation, но даже если это так, я подумал, что на этом этапе bean-компоненты уже будут объявлены, так что жаль, что родительский контекст владеет ими.

Теперь, еще один трюк ... чтобы получить мой DAO, я мог не @Autowired его. Мне пришлось вручную ввести его через XML:

    
    

Конечно, я сделал методы получения и установки на моем дао, и вуаля! Я не знаю, почему здесь не работает @Autowired. Я предполагаю, что это задумано. Возможно, это характерно для SecurityContext (он не будет извлекаться из других контекстов), или, возможно, @Autowired в целом только извлекает из текущего контекста, или, может быть, потому, что я создал bean-компонент через XML, я также должен устанавливать какие-либо свойства через xml, а не через аннотации? (аннотации включены и работают в моем пространстве имен приложения верхнего уровня).

В любом случае ... я еще многого не понимаю, но важно то, что он наконец-то заработал.

24
задан Cœur 1 August 2017 в 15:15
поделиться