Mit Hibernate 4 s Integrator Muster und Spring dependency injection
Bin ich verwendet, um mit Frühling zu tun, meine dependency injection wie so:
<context:component-scan base-package="org.emmerich.myapp" />
und dann kommentieren mein abhängige Klassen mit Autowired
etwa so:
public class DependentClass {
@Autowired
private Dependency dependency;
}
Jedoch, mit den änderungen in der Hibernate 4.0, jetzt sind wir empfohlen, um die neue Integrator
- Schnittstelle für service-discovery. Dies beinhaltet auch das hinzufügen von Ereignis-Listenern für Trigger wie postUpdate
, postDelete
etc.
Leider nicht spielen schön mit dependency injection durch kommentierte Abhängigkeiten. Ich habe Folgendes setup:
Integrator habe ich definiert, um meine Zuhörer zu den ServiceFactory
. Dies ist auf die in der Datei META-INF/services/org.hibernate.integrator.spi.Integrator
.
public class MyIntegrator implements Integrator {
private MyListener listener;
public MyIntegrator() {
listener = new MyListener();
}
@Override
public void integrate(Configuration configuration,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
final EventListenerRegistry eventRegistry =
serviceRegistry.getService(EventListenerRegistry.class);
eventRegistry.prependListeners(EventType.POST_COMMIT_INSERT, listener);
}
Ich auch definiert haben, die Klasse MyListener
, die aussieht wie Ihre typische Ereignis-listener.
@Component
public class MyListener implements PostInsertEventListener {
@Autowired
private Dependent dependent;
public void onPostInsert(PostInsertEvent event) {
//dependent == null
}
}
Nur leider, wie gezeigt, durch den Kommentar, das funktioniert nicht. Ich denke, es ist weil ich bin instanziieren MyListener
innen MyIntegrator
es nicht wählen Sie die Komponente und nicht autowire-Komponenten. Allerdings, wenn ich versuche dieses:
@Component
public class MyIntegrator {
@Autowired
private MyListener listener;
...
}
Dann den Hörer ist nicht autowired.
Erstens, es fühlt sich falsch an, während Sie mit Frühling zu tun haben new MyListener()
. Ich erwarte in der Lage sein zu definieren, die als autowired Abhängigkeit und Frühjahr erstellen einer singleton-für mich. Meine Frage ist:
Was ist der beste Ansatz zur Verwendung von dependency injection mit den neuen Integrator-Schnittstelle? Die Integratoren werden verwendet, um eine SessionFactory, und so, wenn Sie aufgefordert werden, sich integrieren, ich denke, es ist nicht ein Anwendungskontext zur Verfügung. Weil das so ist, alle Bohnen, die ich in die Integrator erstellt werden müssen, die "altmodische" Art und Weise und nicht erhalten die autowiring auf Sie.
Ich bin ziemlich neu in der Welt des Frühlings, würden Sie sagen, das ist etwas, das sollte ich erwarten, zu sehen? Ich verstehe, dass ich bin in einem anderen Bereich der Anwendung, wenn ich mich in die SessionFactory, aber gibt es eine Möglichkeit, um eine Referenz auf die bean und aktivieren autowire obwohl ich erstelle es über new
?
Die Lösung kam ich mit verwendet ApplicationContextAware
. Es bedeutete, dass MyListener
erhalten einen Verweis auf die ApplicationContext
wenn der Kontext verfügbar war, und ich auf die Bohnen aus dem Kontext auf die Methode aufrufen, anstatt sich auf die bean-Konstruktion. Erstellen einer bean mit new
nicht begrenzen diese, so den Frühling gibt mir immer noch die Anwendung Kontext:
@Component
public class MyListener implements PostInsertEventListener, ApplicationContextAware {
private static ApplicationContext context;
public void onPostInsert(PostInsertEvent event) {
//getDependent() == correct!
}
public void setApplicationContext(ApplicationContext context) throws BeanException {
this.context = context;
}
public Dependent getDependent() {
return context.getBean(Dependent.class);
}
}
Gibt es eine bessere Möglichkeit?
- Sie hat nicht vergessen-zu-component-scan
MyIntegrator
Klasse in Ihrem@Autowired
Beispiel? Also, wer ist der Instanziierung desMyIntegrator
Klasse? - Das ist genau die gleiche Lösung kam ich mit zu. Seine arbeiten schön, aber die statische Datei ApplicationContext fühlt sich einfach ein bisschen dreckig 🙂 ich habe es einfach nicht finden ein schöner Weg, da hibernate ist die Schaffung der Integrator. Sobald ich wieder Zeit habe, möchte ich diese eher Abstrakt und haben einen integrator das ist nur ein link um sich anmelden zu können Zuhörer etc erstellt von Frühling. Ich fand einen blog, einmal, aber ich kann mich nicht erinnern, das url jetzt.
- Hibernate erzeugt die
Integrator
für Sie. Geben Sie eine text-Datei in IhremMETA-INF/services
Verzeichnis auf der Liste von Integratoren, die Sie wollen instanziiert und Hibernate baut Sie für Sie vor dem erzeugen der SessionFactory. Irgendwie versteh ich die nicht in der Lage zu Autowire-Komponenten in der Integrator - es ist konstruiert, die außerhalb der Anwendung Anwendungsbereich. Aber ich dachte, es würde möglich sein, mit @Autowired in den Hörer. Und ja, ich bin Rahmen der Prüfung aller Klassen beteiligt. - Ja, ich weiß, was du meinst. Ich habe daran gedacht, einfach einen integrator, aber es fühlte sich nicht richtig an. Hibernate scheint zu wollen, dass Sie angeben, verschiedene Integratoren, dekorieren Sie Ihre
SessionFactory
. Wenn Sie den blog-link, lasst es mich wissen. - Ich habe gerade nochmals überprüft meine Implementierung und schließlich ging ich einen anderen Weg. Grundsätzlich habe ich autowire die HibernateEntityManagerFactory in meinem integrator und Anwender der serviceregistry zu implementieren, die meine Zuhörer. Dieser Weg ist vollständig Frühling wie. Ich poste meinen code als Antwort.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie gesagt in den Kommentar, ich ging einen anderen Weg für die Integration von Spring verwaltet HibernateEventListeners. Hier ist der code:
Dem Bezeichner interface für Spring managed Hibernate-Ereignis-Listener:
Den HibernateIntegrator:
Der "Registry":
Und hier ist ein Beispiel für die Implementierung:
Integrator
- Schnittstelle und Festlegung der integrator text-Datei inMETA-INF/services
?Während eines Upgrades von hibernate 3.6 bis 4.2, die wir brauchten, um eine benutzerdefinierte validator verwendet spring-verwaltete beans, indem Sie die folgende Konfiguration: