2010-03-05 8 views
40

Je possède ce printemps config:Spring Classe d'autowiring par rapport à l'interface?

<bean id="boo" class="com.x.TheClass"/> 

La classe TheClass met en œuvre TheInterface. Ensuite, j'ai cet (hypothétique) du code Java:

@Autowired 
TheInterface x; 

@Autowired 
TheClass y; 

Le autowiring des œuvres TheInterface mais le autowiring de TheClass échoue. Le printemps me donne un NoSuchBeanDefinitionException pour la classe.

Pourquoi pouvez-vous câbler l'interface et non la classe?

+6

Y at-il quelque chose de spécial au sujet de cette classe, comme étant « finale », ou ayant d'autres instruments, comme @Transactional, sur elle. Vous pouvez manquer une librairie d'instrumentation, comme CGLIB, ou essayer de créer un proxy de sous-classe sur une classe finale. – ptomli

Répondre

54

Normalement, les deux fonctionneront, vous pouvez lier automatiquement les interfaces ou classes.

Il y a probablement un générateur autoproxy quelque part dans votre contexte, qui entoure votre bean boo dans un objet proxy généré. Cet objet proxy implémentera TheInterface, mais ne sera pas TheClass. Lorsque vous utilisez les autoproxies, vous devez programmer sur l'interface, pas sur l'implémentation.

Le candidat probable est proxies transactionnels - utilisez-vous les transactions de printemps, en utilisant AspectJ ou @Transactional?

+0

Oui, elle a '@ Transactional', ressemble à ce scénario est invalide .. –

+5

@Marcus: C'est le problème alors. Si vous utilisez '@ Transactional' et' ', vous ne pouvez pas convertir le bean en' MyClass', vous devez utiliser l'interface. – skaffman

+27

Je sais que c'est un peu vieux, mais d'ajouter un peu ici ... Vous ne pas _obligatoire_ d'utiliser l'interface, mais pour lier automatiquement la classe directement, vous devez modifier le ' 'configuration et ajoute' proxy-target-class = "true" '(par défaut c'est faux). Cela vous permet de vous connecter automatiquement à la classe. Notez qu'il peut y avoir des effets secondaires bizarres, par ex. J'avais utilisé une réflexion pour trouver le type paramétré pour une classe de base générique. L'héritage est modifié en raison de la classe proxy, donc je devais en tenir compte. Vous pouvez toujours câbler par l'interface avec 'proxy-target-class =" true "'. –