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 des MyIntegrator 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 Ihrem META-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.
InformationsquelleAutor EMMERICH | 2013-04-15
Schreibe einen Kommentar