2014-10-26 5 views
1

Я прочитал много вопросов об автопогрузке на Stackoverflow, но я до сих пор не могу понять, почему моя автоустановка не работает.Автомойка bean is null

У меня есть стандартная структура каталогов:

com.mycompany 
    |-controller 
    |-service 
    |-model 

Когда я впрыснуть услуги от контроллеров, все работает отлично. Но когда я пытаюсь дать пользовательскую реализацию UserDetailService к прыжку безопасности, он не:

@Service 
public class MyCustomUserDetailService implements UserDetailsService { 

    @Autowired 
    private UserService userService; //This attribute remains null 

    @Override 
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { 
    try { 
     User userByEmail = userService.findUserByEmail(email); //NullPointerException 
     return new UserDetailsAdapter(userByEmail); 
    } catch(NoResultException e) { 
     return null; 
    } 
    } 
} 

UserService является очень простым сервисом, аннотированный с @Service:

import org.springframework.stereotype.Service; 

@Service 
public class UserService { 
    [...] 
} 

Примечания: UserService правильно autowired когда инстанцирован от UserController:

@RestController 
@RequestMapping("/user") 
public class UserController { 

    @Autowired 
    private UserService service; //This one works! 

Вот диспетчер-servlet.xml (см компонент-сканирование):

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xmlns:mvc="http://www.springframework.org/schema/mvc" 
     xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> 

    <context:component-scan base-package="com.mycompany"/> 
    <tx:annotation-driven/> 
    <mvc:annotation-driven/> 
</beans> 

А вот соответствующая часть контекста Spring:

<beans:bean id="customUserDetailService" class="com.mycompany.service.customUserDetailService"/> 

<authentication-manager> 
    <authentication-provider user-service-ref="customUserDetailService"> 
    </authentication-provider> 
</authentication-manager> 

Любая идея?

ответ

3

Я уверен, что ваша проблема связана с тем, что ваш компонент управляется контекстом DispatcherServlet вместо корневого контекста. Поместив <context:component-scan base-package="com.mycompany"/> в контекст DispatcherServlet, все бобы, отсканированные в этих пакетах, будут управляться контекстом DispatcherServlet и не будут видны корневым контекстом, который управляет вашим bean-компонентом MyCustomUserDetailService.

DispatcherServlet является дочерним элементом корневого контекста и позволяет вашим основным компонентам из корневого контекста вводиться в виде компонентов, таких как контроллеры. Видимость - это только один способ: вы не можете вводить bean-компоненты из контекста DispatcherServlet в bean-интерфейс, управляемый корневым контекстом, поэтому он работает в UserController, но не в MyCustomUserDetailService.

Перемещение тега <context:component-scan base-package="com.mycompany"/> в корневой контекст (контекст Spring) должно делать трюк.