Frühling: Injizieren einer privaten inneren Klasse als Mitglied einer äußeren Klasse?
-
23-09-2019 - |
Frage
Ich habe die folgende Klassenstruktur
public class Outer{
private Mapper a;
....
private class MapperA implements Mapper {
}
private class MapperB implements Mapper {
}
}
In meiner Spring -Konfigurationsdatei möchte ich eine äußere Bohne erstellen und einen von Mappera oder MapperB als Eigenschaft zuweisen. Ist das möglich?
<bean id="outer" class="mypackage.Outer">
<property name="a" ?????='????' />
</bean>
Bearbeiten: Einige weitere Informationen, basierend auf dem Feedback aus Antworten:
Ich wurde faul mit meinem obigen Beispiel. Ich habe einen öffentlichen Setter/Getter für die Mapper -Instanzvariable.
Der Grund, warum alle Mapper -Klassen innere Klassen sind, ist, dass es möglicherweise viele von ihnen geben könnte und sie immer nur in dieser Klasse verwendet werden. Ich möchte einfach nicht eine Menge Kreuzklassen in meinem Projekt. Vielleicht ist eine Werksmethode eine bessere Idee.
Lösung
Normalerweise benötigen Sie einen Setter für die Mapper
innerhalb Outer
, und eine Instanz der erforderlichen Mapper
. Aber wie diese sind:
- Privatgelände
- innere
Klassen, das wird etwas schwierig (wie Sie identifiziert haben). Wenn Sie sie öffentlich machen, können Sie sicher eine Instanz verwenden Outer$MapperA
usw. Aber das scheint etwas böse. So:
- Müssen sie inner und privat sein?
- Vielleicht kann äußeres eine Saite nehmen und daraus bestimmen, ob Sie instanziiert werden sollen
MapperA
oderMapperB
. dh hier gibt es einige Werksfunktionen.
Am einfachsten ist es, wirklich festzustellen, ob sie inner/privat sein müssen. Wenn ja, sollten sie wirklich nicht in der Konfiguration verwiesen werden, was über öffentlich zugängliche Klassen sprechen sollte.
Andere Tipps
Frühling kann instanziieren private
innere Klassen. Das tatsächliche Problem mit Ihrer Konfiguration ist, dass sie auch nicht sindstatic
, also brauchst du eine <constructor-arg .../>
:
<bean id="outer" class="mypackage.Outer">
<property name = "a">
<bean class = "mypackage.Outer.MapperA">
<constructor-arg ref = "outer" />
</bean>
</property>
</bean>
Soweit ich weiß, ist es unmöglich, bis Sie machen MapperA
und MapperB
übliche öffentliche Klassen.
Aber wenn Sie sie als innere private Klassen behalten möchten, können Sie sie manuell "injizieren".
Sie müssen Methode mit erstellen @PostInit
Annotation und initialisieren Sie Ihre a
Feld dort (a = new MapperA ()
zum Beispiel oder etwas Komplexeres). Mit diesem Ansatz sollten Sie auch überprüfen, ob die Initialisierungs-Rückrufe in Ihrer Federkonfiguration eingeschaltet sind.