Почему этот боб не вводится?

Я привык использовать Spring и Spring Security, но не могу понять, почему здесь не работает внедрение зависимостей. У меня есть приложение с двумя базовыми системами аутентификации, одна для пользователей и одна для двух администраторов. Это файл security-context.xml:

<http use-expressions="true">
    <intercept-url pattern="/" access="isAuthenticated()" />
    <intercept-url pattern="/*" access="isAuthenticated()" />
    <intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')" />
    <intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')" />
    <http-basic />
</http>

<beans:bean id="userDetailsServiceImpl"
    class="com.foo.bar.service.LoginServiceImpl" />

<authentication-manager>
    <authentication-provider user-service-ref="userDetailsServiceImpl" />
    <authentication-provider>
        <password-encoder hash="md5" />
        <user-service>
            <user name="AdminOne" password="eh223rh2efi9hfuwefugwg"
                authorities="ROLE_ADMIN" />
            <user name="AdminTwo" password="wdkjbcfwerjkbiwfviwefi"
                authorities="ROLE_ADMIN" />
        </user-service>
    </authentication-provider>
</authentication-manager>

Аутентификация пользователя зависит от этой реализации UserDetailsService:

public class LoginServiceImpl implements UserDetailsService {

@Autowired
UserDetailsDAO dao;

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {

    try {
        // Get the credentials
        return credentials;
    } catch (NoResultException exc) {

        throw new UsernameNotFoundException("username not found");
    } catch (JDBCException jdbce) {
        throw new DataAccessException("Cannot acess db", jdbce) {
            private static final long serialVersionUID = 1L;
        };
    }
}

Проблема в том, что поле UserDetailsDAO равно null. Так что не вводится. Странно то, что в тестовой среде все работает нормально. И никаких исключений при запуске сервера не выбрасывается, что тоже странно, т.к. обычно сообщается об ошибках автомонтирования. Кстати, аутентификация администраторов работает как шарм.

Если это может быть полезно, это web.xml: foo

<servlet>
    <servlet-name>Foo Dispatcher Servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
        <!-- Here the context specific for a single project -->
        /WEB-INF/spring/root-context.xml
                /WEB-INF/spring/datasource-context.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>StreamViewer Dispatcher Servlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    <!-- Here the context for all the projects -->
        /WEB-INF/spring/security-context.xml
    </param-value>
</context-param>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

person Fabio    schedule 21.11.2012    source источник


Ответы (2)


Вы должны иметь <context:annotation-config /> в своем security-context.xml, чтобы включить AutowiredAnnotationBeanPostProcessor, который устанавливает значения @Autowired аннотированных полей.

Из документации:

AutowiredAnnotationBeanPostProcessor по умолчанию будет зарегистрирован XML-тегами «context:annotation-config» и «context:component-scan». Удалите или отключите конфигурацию аннотаций по умолчанию, если вы собираетесь указать пользовательское определение bean-компонента AutowiredAnnotationBeanPostProcessor.

См. раздел Является ли context:annotation-config альтернативой @AutoWired?

person Boris Treukhov    schedule 21.11.2012

Если вы хотите использовать автопроводку, вам нужно будет сканировать bean-компоненты, а не объявлять их явно в вашем xml-файле.

Вы должны заменить

<beans:bean id="userDetailsServiceImpl"
    class="com.foo.bar.service.LoginServiceImpl" />

с участием:

<context:component-scan base-package="com.foo.bar" />

и аннотируйте свой класс LoginServiceImpl следующим образом:

@Service(name="userDetailsServiceImpl") 
person Alex Barnes    schedule 21.11.2012