2017-04-21 5 views
2

Ich habe RestController Klasse, die Presenter ruft, um einige Daten zu erhalten.Frühling Autowired Service ist null

@RestController 
@RequestMapping(value="notes/api") 
public class NotesRestController { 

private GetAllNotesPresenter getAllNotesPresenter; 

@RequestMapping(value="/all") 
public List<Note> getAll(){ 
    getAllNotesPresenter = new GetAllNotesPresenterImpl(); 
    return getAllNotesPresenter.getAll(); 
} 

}

Innen Presenter-Klasse-I rufen Datasource (nicht Repository Spring, nur DAO-Klasse).

public class GetAllNotesPresenterImpl implements GetAllNotesPresenter { 

private NotesDataSource dataSource; 
private NotesRepository repository; 

public GetAllNotesPresenterImpl(){ 

    dataSource = new DatabaseDataSource(); 
    repository = new NotesRepositoryImpl(dataSource); 
} 
@Override 
public List<Note> getAll() { 
    return repository.getAll(); 
} 

}

Das ist meine Repository-Klasse, es ist nicht Repository Frühling, es ist nur DAO-Klasse.

public class NotesRepositoryImpl implements NotesRepository { 

private NotesDataSource dataSource; 

public NotesRepositoryImpl(NotesDataSource dataSource){ 
    this.dataSource = dataSource; 
} 

@Override 
public List<Note> getAll() { 
    return dataSource.getAll(); 
} 

}

Das ist mein Service-Klasse:

@Service 
@Transactional 
public class NotesServiceImpl implements NotesService { 

@Autowired 
private NotesJpaRepository repository; 

@Override 
public List<NoteJpa> getAll() { 
    return repository.findAll(); 
} 

}

Innere Datasource-Klasse möchte ich @Autowire of Spring Dienst tun, aber ich Null-Zeiger-Ausnahme . Der Dienst ist immer null.

@Component 
public class DatabaseDataSource implements NotesDataSource { 

@Autowired 
private NotesService notesService; 

public DatabaseDataSource(){ 
} 

@Override 
public List<Note> getAll() { 
    return notesService.getAll(); 
} 

}

+0

Wenn der obige Code korrekt ist, denke ich, dass der 'NotesService' niemals konstruiert wird (und vorher eine Ausnahme auslöst), weil er ein' NotesJpaRepository' erwartet, das Sie entweder nicht erwähnen oder kein Bean ist. Wenn dies die Implementierung von 'NotesRepository' sein soll, muss es instanziiert und als eine Bean exponiert werden. – meistermeier

+0

Haben Sie @ Service Annotation in "NotesService" -Schnittstelle? – VelNaga

Antwort

1

Auch wenn Sie die DatabaseDataSource als @Component kommentiert haben, Sie sind nicht eingespritzt wird, und damit, sie als Frühlings Bean auf dem Weg. Sie schaffen es einfach von Hand:

public GetAllNotesPresenterImpl(){ 

    dataSource = new DatabaseDataSource(); 
    repository = new NotesRepositoryImpl(dataSource); 
} 

Um die Vorteile der Injektion dieser Bohne zu nehmen:

@Autowired 
private NotesService notesService; 

Sie müssten Frühling Injektion verwenden, um von oben nach unten (dies ist nur eine der ist Wege kann man darüber gehen):

1) die Datenquelle in der Steuerung injizieren:

@RestController 
@RequestMapping(value="notes/api") 
public class NotesRestController { 

private GetAllNotesPresenter getAllNotesPresenter; 

@Autowired 
private NotesDataSource dataSource; 

@RequestMapping(value="/all") 
public List<Note> getAll(){ 
    getAllNotesPresenter = new GetAllNotesPresenterImpl(dataSource); 
    return getAllNotesPresenter.getAll(); 
} 

2) den Konstruktor der GetAllNotesPresenterImpl ändern:

public GetAllNotesPresenterImpl(NotesDataSource dataSource){ 

    this.dataSource = dataSource; 
    repository = new NotesRepositoryImpl(dataSource); 
} 

Andere Option wäre GetAllNotesPresenterImpl und NotesRepositoryImpl als Feder Bohnen zu machen und Datasource im NotesRepositoryImpl direkt zu injizieren. Der letzte Anruf liegt bei Ihnen.

+0

Ja, das funktioniert :) Ich brauche eine Erklärung. Was würde passieren, wenn ich mehrere Implementierungen von NotesDataSource hätte. Zur Zeit habe ich nur DatabaseDataSource, die diese NotesDataSoruce-Interfexe implementieren, die in meine RestController-Klasse injizieren. – Zookey

+0

Sie würden @Qualifier-Annotation verwenden, um anzugeben, welche Implementierung explizit für die Injektion verwendet werden soll. –

+0

Danke!Wenn Sie möchten, können Sie das hinzufügen, vielleicht mit Beispiel, weil viele Leute nach dieser Art von Frage suchen. Es wird vielleicht jemandem nützlich sein. – Zookey