Spring SecurityからJpaRepositoryがAutowiredできなくてハマったまま

Spring Securityを使ってユーザ認証とアクセス制御を試して見ようという事で、実装にチャレンジして、ハマった話（というか脱出できなかった話）。殴り書きご容赦。

#エラー
ユーザフォームにusernameとpasswordを入力し「ログイン」ボタンを押すと以下のエラーが発生

```
Caused by: java.lang.NullPointerException
	at com.ec.train03.service.CustomUserDetailsService.loadUserByUsername(CustomUserDetailsService.java:69)
	at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:114)
	... 46 more
```

#現象
デバッガでこれを辿ると、JpaRepositoryが、SecurityFilter側からコールされるとAutowiredされない現象が発生している。「CustomUserDetailsService」はNullで無く、この「loadUserByUsername」内から参照されているuserRespositoryがNullになっている。

``` CustomDetailService
@Service
public class CustomUserDetailsService implements UserDetailsService {

	@Autowired
	private CustomUserDetailsRepository customUserDetailsRepository; ←★ここがAutowiredされない
	
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

       // TODO 自動生成されたメソッド・スタブ
        if (username == null || "".equals(username)) {
            throw new UsernameNotFoundException("Username is empty");
        }
                
        User user = customUserDetailsRepository.findByUsername(username);
        
        if (user == null) {
            throw new UsernameNotFoundException("User not found: " + username);
        }
        return user;
	}
}
```


下の「図モドキ」は正しく書けてはないが、ざっと処理のイメージです。

userDetailsService　← (Autowired) ←userRepository←DB(PostgreSQL)
.loadUserByUsername
 ↑　　　　　↓　UserDetails
DaoAuthenticationProvider
 ↑
SecurityFilter

**userDetailsServiceのプロパティにuserRepositoryをAutowiredを設定している**

Spring data jpaを使ってユーザ情報と権限情報をPosgreSQLのテーブルに保持する。

#原因
不明。

#確認した事
　突き止めるために調べたり、試したりした事。
　①Annotationをミスしてないか？(@Repositoryの付け忘とか、@Serviceの付け忘れとか）
　　、、、そもそもWeb.xmlとかpom.xmlとかservlet-context.xmlとかも
　②ComponetScanの設定漏れとかミスとか
　③JpaRepositoriesの設定漏れとかミスとか
　④@Autowiredの設定ミス？
　⑤xmlでの設定や、Javaconfigで挙動が違う？（どちらでも再現する？）
　⑥springのVersionの問題？
　　spring-securityやSpring-data-jpaのVersionの問題？
   （結局、Versionの問題を調べられるノウハウが無かった）
　　springframework 4.3.25.RELEASE
　　spring-security 4.2.0.RELEASE
　　spring-data-jpa 1.11.4.RELEASE
 
　**⑦Jpa絡みの機構が動いてるか？確認するために、⑥の組合せで、認証用のUser（UserDetails)のEntitiyをWebの画面から
　　入力して永続化(テーブル保存)、１件参照、一覧参照を実装して、動作する事を確認した**　→　動いた。
　
　⑧Autowiredがダメなのか？と思って、UserDetailsServiceをnewしてconfigureでセットしたが、この場合、当たり前だがuserRepositoryはAutowiredされない。

　最後は、テンパってしまって、JpaRespositoryをインプリして、インプリクラス実装しようかと思ったが、それってJpaを利用するメリットを全部投げ捨てる事で「本末転倒するぎる」って事でやめました、、、

#似た話
検索して回ったもの。解決してないようにみえるもの。

- Autowire doesn't work for custom UserDetailsService in Spring Boot  
 https://stackoverflow.com/questions/38647002/autowire-doesnt-work-for-custom-userdetailsservice-in-spring-boot
- Custom UserDetailsService it seems to be not autowired  
  https://stackoverflow.com/questions/35344135/custom-userdetailsservice-it-seems-to-be-not-autowired
- Spring fails to autowire repository  
  https://stackoverflow.com/questions/32067571/spring-fails-to-autowire-repository
- Autowired CrudRepository into UserDetailsService is always null  
 https://stackoverflow.com/questions/25536596/autowired-crudrepository-into-userdetailsservice-is-always-null
- Why is my Spring @Autowired field null?  
  https://stackoverflow.com/questions/19896870/why-is-my-spring-autowired-field-null


#暫定として（SpringBoot）
　⑥で実装したものとは別に、Spring Boot 1.5.22で実装したら、所定の動作で認証できたので、やはり何かの組合せ問題だろうかと、想像している。

　そもそもなんで、今時ナマのSpringframeworkって話なのだけど、基本的な動作を追跡するためにやってるのだけども。