Bei der Integration der Spring- und Hibernate-Frameworks sind kürzlich eine Reihe von Ausnahmen aufgetreten. In diesem Artikel werden hauptsächlich mögliche Ausnahmen und Lösungen im Spring-Framework erläutert.
Wir verwenden den leistungsstarken Bean-Container-Verwaltungsmechanismus von Sping, um die Lebenszyklusverwaltung von Javabean über BeanFactory einfach zu realisieren. Bei der Konfigurationsverwaltung werden wir jedoch zwangsläufig auf einige Ausnahmen stoßen:
Ausnahme 1: Nein Qualifizierende Bean vom Typ […] für Abhängigkeit gefunden
Zum Beispiel wird BeanB automatisch in BeanA eingefügt
@Component
öffentliche Klasse BeanA {
@Autowired
private BeanB-Abhängigkeit;
…
}
Wenn BeanB zu diesem Zeitpunkt nicht im Cntextl von sping definiert ist, wird beim Start eine Ausnahme ausgelöst: die Ausnahme ohne solche Bean-Definition:
org.springframework.beans.factory.NoSuchBeanDefinitionException:
Keine qualifizierende Bean vom Typ [org.baeldung.packageB.BeanB] für Abhängigkeit gefunden:
mindestens 1 Bean erwartet, die als Autowire-Kandidat für diese Abhängigkeit qualifiziert.
Abhängigkeitsanmerkungen: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Der Grund für das Problem ist einfach, dass mindestens eine Bean erwartet wird, die dafür als Autowire-Kandidat in Frage kommt Für die Abhängigkeitsinjektion ist mindestens eine definierte Bean erforderlich. Ein weiterer möglicher Grund ist natürlich, dass wir bei der Verwendung von Annotationen und der Konfiguration des Annotations-Scans den Pfad für das Paket-Scannen nicht festgelegt haben. Andernfalls sollte keine Bean definiert sein.
Ausnahme 2: Es ist keine qualifizierende Bean vom Typ […] definiert
Diese Ausnahme bedeutet, dass es keine qualifizierende Bean vom Typ gibt. Der Grund dafür ist, dass wir zwei oder mehr identische Beans definiert haben Es ist nicht die einzige Bean. Es gibt beispielsweise eine Schnittstelle IBeanB und ihre beiden Implementierungsklassen Bean1 und Bean2
@Component
öffentliche Klasse BeanB1 implementiert IBeanB {
//
}
@ Component
öffentliche Klasse BeanB2 implementiert IBeanB {
//
}
Zu diesem Zeitpunkt weiß Spring nicht, welche Implementierungsklasse er verwenden soll, wenn BeanA die Schnittstelle IBeanB injiziert inject
@Component
public class BeanA {
@Autowired
private IBeanB dependency;
…
}
Zu diesem Zeitpunkt BeanFactory löst eine Ausnahme aus: NoSuchBeanDefinitionException
Verursacht durch: org.springframework.beans.factory.NoUniqueBeanDefinitionException:
Keine qualifizierende Bean vom Typ [org.baeldung.packageB.IBeanB] ist definiert:
einzelne Übereinstimmung erwartet Bean aber gefunden 2: beanB1, beanB2
Aus der Ausnahme „einzelne passende Bean erwartet, aber 2 gefunden“ ist ersichtlich, dass die einzige Bean nicht gefunden wurde
Dann kann es gelöst werden mit der folgenden Methode
@Component
öffentliche Klasse BeanA {
@Autowired
@Qualifier(“beanB2”)
private IBeanB-Abhängigkeit;
…
}
Sping weiß genau, welche Bean als Objekt für die Injektion verwendet wird
Ausnahme 3: Es ist keine Bean mit dem Namen […] definiert
Wenn diese Ausnahme auftritt, Gehen Sie zum Sping-Kontext, um die Bean anhand des Namens zu finden. Es kann zu einer Ausnahme kommen ;
@Override
public void afterPropertiesSet() {
}
}
Bei der Suche hier gibt es Keine Definition mit dem Namen „someBeanName“, was zu einer Ausnahme führt
Verursacht durch: org.springframework.beans.factory.NoSuchBeanDefinitionException:
Keine Bean mit dem Namen „someBeanName“ ist definiert
Wenn eine Bean den dynamischen JDK-Proxy-Mechanismus im Spring-Kontext verwendet, erbt die Proxy-Klasse nicht das Zielobjekt, sondern implementiert dafür die gleiche Schnittstelle Grund: Wenn eine Bean in eine Schnittstelle eingefügt wird, gibt es kein Problem. Wenn es sich jedoch um eine Implementierungsklasse handelt, kann der Sping-Container die Bean zu diesem Zeitpunkt nicht finden, da die Proxy-Klasse das Ziel nicht erbt Klasse. Ein sehr häufiges Szenario, warum eine Bean als Proxy verwendet wird, ist die Verwendung der Transaktionsunterstützungsfunktion von Spring. Sie können die Annotation @Transactional verwenden, um eine Transaktion anzugeben, oder Sie können sie in der Konfigurationsdatei festlegen.
Wenn beispielsweise ServiceA ServiceB injiziert und beide Dienste mit Transaktionen konfiguriert sind, treten durch die Klasseninjektion Probleme auf.
@Service
@Transactionalpublic class ServiceA implementiert IServiceA{
@Autowired
private ServiceB serviceB;…
}
@Transactional
öffentliche Klasse ServiceB implementiert IServiceB{
…
}
Die gleichen beiden Dienste werden normal ausgeführt, wenn Schnittstelleninjektion verwendet wird.
@Service
@Transactional
public class ServiceA implementiert IServiceA{
@Autowired
private IServiceB serviceB;…
}
@Transactional
öffentliche Klasse ServiceB implementiert IServiceB{
…
}