2014-10-26 115 views
1

我已經閱讀了很多關於在Stackoverflow上自動裝配的問題,但我仍然無法確定爲什麼我的自動裝配不起作用。Autowired bean爲null

我有一個標準的目錄結構:

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

當我從控制器注入服務,一切工作正常。但是,當我試圖給的UserDetailService一個定製實現Spring Security的,它失敗:

@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 anotated:

import org.springframework.stereotype.Service; 

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

注:UserService正確自動裝配時從UserController實例化:

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

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

以下是dispatcher-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

我敢肯定,你的問題與你的bean由DispatcherServlet上下文而不是根上下文管理有關。通過將<context:component-scan base-package="com.mycompany"/>置於DispatcherServlet上下文中,在這些軟件包上掃描的所有bean將由DispatcherServlet上下文進行管理,並且由管理您的MyCustomUserDetailService bean的根上下文不可見。

DispatcherServlet是根上下文的子節點,它允許從根上下文中將核心bean注入到視圖層bean中,如控制器。可見性只有一種方法,您不能將DispatcherServlet上下文中的bean注入由根環境管理的bean中,這就是爲什麼它可以在UserController中運行,但不能在MyCustomUserDetailService中運行。

<context:component-scan base-package="com.mycompany"/>標記移動到根上下文(Spring上下文)應該有所訣竅。