2017-02-07 10 views
1

今、私はリポジトリに接続しようとしているAPIクライアントタイプのクラスを持っているので、MySQLデータベースにデータを格納できます。java - Springブートでインスタンス化されるクラスのAutowiringリポジトリ

私が抱えている問題は、APIクライアントクラスが新しいオブジェクトをインスタンス化するため、Autowiringが正しく機能しないということです。私はこの問題の回避策を見てきましたが、いくつかのオプションがありましたが、問題にどのように適用するのか混乱しています。

GeniusApiClient.java:

@Component 
public final class GeniusApiClient { 
    private final OkHttpClient client = new OkHttpClient(); 

    @Autowired 
    private ArtistDao artistDao; 

    public static void main(String[] args) throws Exception { 
     GeniusApiClient geniusApiClient = new GeniusApiClient(); 
     String artistId = (geniusApiClient.getArtistId("Ugly Duckling")); 

     ArrayList<String> artistSongIds = geniusApiClient.getArtistSongIds(artistId); 
     System.out.println(geniusApiClient.getAllSongAnnotations(artistSongIds, artistId)); 
    } 

    public String getAllSongAnnotations(ArrayList<String> songIds, String artistId) { 
     Artist artist = new Artist("test name for now", "string123", "223"); 
     artistDao.save(artist); 
     return "finished"; 
    } 

} 

ArtistDao.java:

@Transactional 
public interface ArtistDao extends CrudRepository<Artist, Long> { 
    public Artist findByGeniusId(String geniusId); 
} 

ArtistController.java:

は参考のため、ここでは関係のファイルのいくつかの部分であり、

@Controller 
public class ArtistController { 
    @Autowired 
    private ArtistDao artistDao; 

    /** 
    * GET /create --> Create a new artist and save it in the database. 
    */ 
    @RequestMapping("/create") 
    @ResponseBody 
    public String create(String name, String annotations, String genius_id) { 
     String userId = ""; 
     try { 
      genius_id = genius_id.replaceAll("/$", ""); 
      Artist artist = new Artist(name, annotations, genius_id); 
      artistDao.save(artist); 
      userId = String.valueOf(artist.getId()); 
     } 
     catch (Exception ex) { 
      return "Error creating the artist: " + ex.toString(); 
     } 
     return "User succesfully created with id = " + userId; 
    } 

    /** 
    * GET /get-by-email --> Return the id for the user having the passed 
    * email. 
    */ 
    @RequestMapping("/get") 
    @ResponseBody 
    public String getByEmail(String genius_id) { 
     String artistId = ""; 
     try { 
      Artist artist = artistDao.findByGeniusId(genius_id); 
      artistId = String.valueOf(artist.getId()); 
     } 
     catch (Exception ex) { 
      return "User not found"; 
     } 
     return "The user id is: " + artistId; 
    } 

} 

問題は、getAllSongAnnotationsメソッドのGeniusApiClient.javaでは、artistDaoにアクセスしようとするとnullポインタ例外が発生することです。私はこのクラスのインスタンス化がオートワイヤリングを台無しにしていることを理解していますが、これを修正する最善の方法が何であるか不思議です。

新しいメソッドをインスタンス化する必要がないように、クラス内のすべてのメソッドを静的にすることを検討しましたが、これはうまくいくとは思われません。助言がありますか?

おかげ

EDIT:

は、わかりやすくするために、いくつかの無関係なコードを削除しました。

EDIT2:あなたのcatchブロックでやろうとしている何を追加しましたArtistController.java

答えて

3

オブジェクトをautowire/injectできるようにするには、そのオブジェクトはSpring Beanでなければなりません。

ここでは、ArtistDaoは、Beanではないため、オートワイヤできません。 Beanにするにはいくつかのアノテーションオプションがありますが、この場合のスーツは@Repository注釈です。 GeniusApiClientクラスで使用した@Componentの特殊バージョンです。

ので、

@Repository 
@Transactional 
public interface ArtistDao extends CrudRepository<Artist, Long> { 
    public Artist findByGeniusId(String geniusId); 
} 

は動作するはずです。

私はあなたが読むことをお勧めしたい:参考資料を読むことあなたに怖い聞こえるhttp://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html

場合は、コア春Spring in Action部分を見てみることができます。

+0

あなたの答えをありがとう! @Repository注釈を追加しようとしましたが、無駄です。私は、私が実際にArtistDaoクラスを私のファイルの別の1つにAutowireすることができたと言及しておかなければならないと言いたいと思います。Spring Controller。問題は他の場所にあるかもしれないと思っています。私は、私が正常にArtistDaoをautowiredしたクラスを含むように投稿を編集します。 –

+0

ああ、私はあなたが 'GeniusApiClient'の新しいインスタンスを作成し、このインスタンスから' ArtistDao'にアクセスするので、あなたが作成したインスタンスについてのSpringは 'ArtistDao'をautowireできないことに気付きました。新しいインスタンスを作成する代わりに 'GeniusApiClient'をオートワイヤして、問題を解決する必要があります。 – sedooe

+0

それはトリック、ありがとう!私はSpringの仕組みに関する多くのギャップがあるようです:P –

0

が私には明確ではない

、あなたはそれを修正し、任意で撮影することが目的のアクションでそれを交換する必要が例外発生。

+0

私はその方法に無関係なコードの一部を削除するために私のポストを編集しました。私の質問は 'artistDao'がなぜnullであるのかと関係しています。 –

1

最終的にGeniusApiClient.classを作成しないでください。SpringはCGLIBを使用して、プロキシを作るためにクラスを動的に拡張します。そして、CGLIBが動作するための要件は、あなたのクラスを非最終的にすることです。ここでは、この上の

より:Make Spring Service Classes Final?

+0

チップをありがとう!私はそれを最終的なものにしないように変更しましたが、残念ながら、私はまだartistDaoをnullにしています。 –

+0

設定クラスまたはxmlを共有してください。 – mhshimul

+0

設定クラスやxmlがあるかどうかわかりません。 Spring BootがSpring MVCとは異なるのかどうかは分かりませんが、私が扱った設定ファイルは 'application.properties'ファイルだけです。 –

関連する問題