2010-03-05 12 views
40

Ich habe diesen Frühling config:Spring Autowiring Klasse vs. Schnittstelle?

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

Die Klasse TheClass Geräte TheInterface. Dann habe ich diesen (hypothetischen) Java-Code:

@Autowired 
TheInterface x; 

@Autowired 
TheClass y; 

Die autowiring von TheInterface funktioniert, aber die autowiring von TheClass ausfällt. Der Frühling gibt mir eine NoSuchBeanDefinitionException für die Klasse.

Warum können Sie die Schnittstelle und nicht die Klasse verdrahten?

+6

Gibt es etwas Spezielles in dieser Klasse, wie "final" oder andere Instrumentierung wie @Transactional. Sie können entweder eine Instrumentierungsbibliothek wie CGLIB vermissen oder versuchen, einen Unterklassenproxy für eine letzte Klasse zu erstellen. – ptomli

Antwort

54

Normalerweise funktionieren beide, Sie können Schnittstellen oder Klassen automatisch ansteuern.

Es gibt wahrscheinlich irgendwo in Ihrem Kontext einen Autoproxy-Generator, der Ihre boo-Bean in ein generiertes Proxy-Objekt einbindet. Dieses Proxy-Objekt implementiert TheInterface, ist jedoch kein TheClass. Wenn Sie Autoproxies verwenden, müssen Sie die Schnittstelle programmieren, nicht die Implementierung.

Der wahrscheinliche Kandidat ist transaktionale Proxys - verwenden Sie Spring-Transaktionen mit AspectJ oder @Transactional?

+0

Ja, es hat '@ Transactional', klingt wie dieses Szenario ist ungültig .. –

+5

@Marcus: Das ist das Problem dann. Wenn Sie '@ Transactional' und' 'verwenden, können Sie die Bean nicht in' MyClass' umwandeln. Sie müssen die Schnittstelle verwenden. – skaffman

+27

Ich weiß, das ist ein bisschen alt, aber um ein bisschen hier hinzuzufügen ... Sie haben _have_ nicht die Schnittstelle zu verwenden, aber um die Klasse direkt zu aktivieren, müssen Sie die 'configuration und füge' proxy-target-class = "true" 'hinzu (dies ist standardmäßig false). Auf diese Weise können Sie sich direkt mit der Klasse verbinden. Beachten Sie, dass es seltsame Nebenwirkungen geben kann, z. Ich hatte einige Überlegungen verwendet, um den parametrisierten Typ für eine generische Basisklasse zu finden. Die Vererbung wurde aufgrund der Proxy-Klasse geändert, also musste ich das berücksichtigen. Sie können weiterhin per Schnittstelle mit 'proxy-target-class =" true "' verbinden. –

Verwandte Themen