Java In statischem Initialisierungsblock auf Spring-ApplicationContext zugreifen

mental.dIseASe

Lieutenant
Registriert
Dez. 2008
Beiträge
676
Heyho,

ich habe eine Domänenklasse A, die Einträge in einer DB spiegelt.

Code:
public class A {
    private Long id;
    private String name;
}

Weiterhin habe ich eine Domänenklasse B, die ein A-Property hat.

Code:
public class B {
    private A a;
}

Außerdem habe ich auf der Serviceschicht einen Spring-managed Manager, der regelmäßig in diversen Stellen der Anwendung dafür da ist, um Objekte der Klasse A aus der DB zu ziehen, bspw.:

Code:
public interface AManager {
    public A get(Long id);
    public A getByName(String name);
}

Da ich an vielen Stellen in der Anwendung Vergleiche habe, die das A-Property eines Bs gegen eine begrenzte Menge bestimmter As aus der DB prüfen, müsste ich die jeweils spezifischen As ja eigentlich jedes mal aus der DB ziehen:

Code:
A aSpecificA = anAManager.getByName("specificIdentifyingString");
A anotherSpecificA = anAManager.getByName("anotherSpecificIdentifyingString");
if (b.getA().equals(aSpecificA) {

} else if (b.getA().equals(anotherSpecificA) {

}

Also würde ich gerne aSpecificA und anotherSpecificA als public static final As in A hinterlegen, also als Konstanten:

Code:
public class A {
    public static final A aSpecificA = AppContext.getBean(AManager.class).getByName("specificIdentifyingString");
    public static final A anotherSpecificA = AppContext.getBean(AManager.class).getByName("anotherSpecificIdentifyingString");

    private Long id;
    private String name;
}

sodass ich dann gegen diese Quasi-Konstanten/Caches prüfen kann und nicht bei jeder derartigen if-Abfrage vorher auf die DB zugreifen muss:

Code:
if (b.getA().equals(A.aSpecificA) {

} else if (b.getA().equals(A.anotherSpecificA) {

}

Meine eigentliche Frage ist jetzt: ist der ApplicationContext während der statischen Initialisierung schon verfügbar oder nicht? Und falls nicht (, was mir mein Instinkt sagt): gibt es irgendeinen Workaround, der sinnvoll erscheint? Enum ist keine Option, weil die möglichen Ausprägungen nicht aufzählbar sind. Die tatsächlichen Domänenklassen sind komplexer als die Beispielklassen oben.
 
Du beschreibst typisches Caching, also baue dir einen Cache auf. Dann werden die aSpecificA usw. nur einmal geladen. Beachte allerdings, dass sich die Objekte in der DB auch ändern können. Evtl. musst du dann den Inhalt der Caches aktualisieren bzw. löschen.

Pass aber mit "equals()" auf", weil es bei dir Objekte vergleicht! Also equals überschreiben bzw. direkt die Attribute vergleichen.
 
Zuletzt bearbeitet:
Diejenige Teilmenge der As, die ich dort als spezifisch bezeichne, sind unveränderlich. Daneben gibt es noch As, die als Ergebnis von Nutzerinteraktion in die DB geschrieben werden, aber die anderen sind tatsächlich konstant. Equals ist durchimplementiert.

Ich habe mir jetzt einen Test für dieses Caching geschrieben, bevor ich das auf das eigentliche System loslasse und es scheint wider Erwarten so zu funktionieren, wie ich gehofft hatte. :) Die Classloading- und Intialisierungsmechanismen sind wirklich ziemlich faszinierend. Sorry, dass ich erst nach dem Posten rumprobiert habe, aber ich hatte zuerst keinen Bock auf unser TestNG hier, weil ich mich damit noch nicht so gut auskenne.

Damit ist das Problem für mich erledigt. Trotzdem vielen Dank für deine Hilfe!
 
Zurück
Oben