2016-11-01 8 views
0

私はSpringプロジェクトでセキュリティを設定していますが、残念ながら問題が発生しました。 CustomUserDetailsS​​ervice.javaのautowired userDAOがnullになるのはなぜですか?ここSpring:カスタムのUserServiceDetails実装でautowired DAOがヌルです

は、問題のコードである:

CustomUserDetailsS​​ervice.java

@Service("customUserDetailsService") 
@ComponentScan(basePackages="...") 
public class CustomUserDetailsService implements UserDetailsService { 

    @Autowired 
    private UserDAO userDAO; 

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 

     // userDAO is null 
     UserModel user = userDAO.getUserByUsername(username); 
     ... 
    } 
} 

ばねのsecurity.xml

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

<http pattern="/resources/**" security="none"/> 
<http pattern="/login" security="none"/> 

<http auto-config="true"> 
    <intercept-url pattern="/**" access="ROLE_USER" /> 
    <form-login 
     login-page="/login" 
     default-target-url="/home" 
     authentication-failure-url="/login?error" 
     username-parameter="username" 
     password-parameter="password" /> 
    <logout logout-success-url="/login?logout" /> 
</http> 

<authentication-manager> 
    <authentication-provider user-service-ref="customUserDetailsService"> 
     <password-encoder ref="encoder" /> 
    </authentication-provider> 
</authentication-manager> 

<beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"> 
    <beans:constructor-arg name="strength" value="10" /> 
</beans:bean> 

<beans:bean id="customUserDetailsService" class="... .service.CustomUserDetailsService" /> 

編集:

UserDAOImpl.javaここ

public class UserDAOImpl implements UserDAO { 

private JdbcTemplate jdbcTemplate; 

public UserDAOImpl(DataSource dataSource) { 
    jdbcTemplate = new JdbcTemplate(dataSource); 
} 

    public UserModel getUserByUsername(String username) { 

     String sql = "SELECT * FROM users WHERE username = '" + username + "'"; 

     return jdbcTemplate.query(sql, new ResultSetExtractor<UserModel>() { 

      public UserModel extractData(ResultSet rs) throws SQLException, DataAccessException { 
       if (rs.next()) { 
        UserModel user = new UserModel(); 
        user.setUsername(rs.getString("username")); 
        user.setPassword(rs.getString("passwort")); 
        user.setEnabled(rs.getBoolean("enabled")); 

        return user; 
       } 
       return null; 
      } 
     }); 
    } 
} 

は、Javaベースの設定ファイル内のコードスニペットです:

@Bean 
public UserDAO getUserDAO() { 
    return new UserDAOImpl(getDataSource()); 
} 

興味深いしかし、この構成は、ソートの動作しているようです。私は私のコントローラにUserDAOをautowireするとき、それは完全に正常に動作します:

MainController.java

@RequestMapping(value = {"", "/", "/home"}) 
public String homeHandler(Model model) { 

    // userDAO is not null, works perfectly fine and returns the UserModel-Object as expected 
    UserModel user = userDAO.getUserByUsername("dx"); 

    ... 
} 

私はすでにいくつかのQ & Aを読んで、まだ今のところは、カスタムUserDetailsS​​erviceのマニュアルinstatiationを懸念。私のコードで何が間違っていますか?

+0

スキャン中ですか? –

+0

Javaの設定ですか?はい、そうです。 DAOを私のメインコントローラ(他のすべてのDAOと同じように)にテストワイヤで自動配線すると、nullではなく正常に動作します(CustomUserDetailsS​​ervice.javaではnullのみです)。 –

+0

'getUserDAO()'メソッドはどこにありますか? – sura2k

答えて

1

この問題は、customUserDetailsServiceを2つの異なる場所でインスタンス化しているために発生しているようです。 spring-security.xmlファイルには<bean>という定義があり、クラス自体には@Service注釈があります。 XML Bean定義では、UserDAOがnullになるように注入していません。

java configファイルまたはXMLファイルのBean定義を整理するためにプロジェクトを合理化する必要があります(これは必須ではなく、XML + java設定を持つこともできますが、Beanのインスタンス化については非常に混乱します) 。オプションはほとんどありません。

  1. CustomUserDetailsServiceのXML宣言を削除します。 XMLに<context:component-scan>を追加し、パッケージ名を追加して@ComponentScanCustomUserDetailsServiceから削除します。これにより、春にパッケージをスキャンし、@Service@Beanなどの注釈が付いた豆を登録できます。 Java設定クラスに@Configuration注釈が付いていることを確認してください。

  2. あなたは、あなたが@Beanを削除する必要があり、その場合には、すべてのBeanのXML設定を使用することを決定@Serviceなどの注釈と春のXMLビーン定義でそれらのすべてを宣言し、それらのそれぞれが適切な依存関係を持っていることを確認することができます注射した。

正しく依存関係が注入されるように、Bean定義をクリーンアップする必要があります。

0

ありがとうございました。 Setuの答えは最も有益な答えでした。明らかに、問題は実際には二重インスタンス化でした。私は<context:component-scan base-package="... .service" />を追加し、@Service("customUserDetailsService")@ComponentScan(basePackages="...")の両方をCustomUserDetailsServiceに残しました(@ComponentScanは機能しませんでした)。

関連する問題