2015-03-08 12 views
7

Ho bisogno di iniettare da @Autowired implementazione concreta di una classe di servizio.Spring: come iniettare l'implementazione concreta dell'interfaccia?

Interfaccia di servizio:

public interface PostService { 
... 
} 

Implementazione:

@Service("postServiceImpl") 
public class PostServiceImpl implements PostService { 
... 
} 

Metodi al servizio sono con annotazione @ Transactional

E ora voglio iniettare postServiceImpl al mio controller - perché ho bisogno utilizzare un metodo dall'implementazione, che non è nell'interfaccia:

@Autowired 
@Qualifier("postServiceImpl") 
private PostServiceImpl postService; 

ottengo NoSuchBeanDefinitionException con il seguente messaggio:

No qualifica di fagioli di tipo [(...) .PostServiceImpl] trovato per dipendenza: previsto con almeno 1 di fagioli che si qualifica come autowire candidato per questa dipendenza.

quando cambio il campo nel mio controller per:

private PostService postService 

funziona, ma non posso usare un metodo specifico da PostServiceImpl.

+3

Quindi aggiungerlo all'interfaccia. Qual è il punto di dichiarare le interfacce se si inietta il tipo concreto? –

+0

Hai qualche aspetto applicato a quel bean? Oppure i proxy basati su interfaccia? – fcracker79

+1

@fcracker79 Penso di esserlo, perché i metodi nel servizio sono con l'annotazione @ Transactional. – tomdavies

risposta

9

Poiché i metodi sono annotati @Transactional, spring creerà il proxy in fase di runtime, per l'inserimento del codice di gestione delle transazioni. Per impostazione predefinita, Spring utilizza JDK Dynamic Proxy per il meccanismo di proxy, che utilizza proxy basati su interfacce.

Quindi, in questo caso, spring crea un'altra classe che implementa l'interfaccia PostService e crea bean di quella classe. Sicuramente, non è possibile autorizzarlo su PostServiceImpl, poiché sono fratelli. Tuttavia, se si desidera veramente eseguire la registrazione in classe, è possibile forzare l'utilizzo del proxy CGLib, che utilizza la sottoclasse. Che puoi fare impostando proxyTargetClass=true nell'annotazione @EnableTransactionManagement, se stai usando la configurazione basata su Java.