Ich verwende Spring, um RMI-Aufrufe an einen Remote-Server zu verarbeiten. Es ist einfach, einen Anwendungskontext zu konstruieren und die Bean für Remote-Aufrufe von innerhalb des Clients zu erhalten:
%Vor%Ich sehe jedoch keine einfache Möglichkeit, Eigenschaften in die Konfiguration zu übernehmen. Zum Beispiel, wenn ich den Host-Namen für den Remote-Server zur Laufzeit innerhalb des Clients ermitteln möchte.
Ich hätte idealerweise einen Eintrag im Spring-Kontext:
%Vor%und übergeben Sie die Eigenschaften an den Kontext vom Client als Parameter.
Ich kann einen PropertyPlaceholderConfigurer im Kontext verwenden, um diese Eigenschaften zu ersetzen, aber soweit ich das beurteilen kann, funktioniert das nur für Eigenschaften, die aus einer Datei gelesen werden.
Ich habe eine Implementierung, die dies anspricht (hinzugefügt als Antwort), aber ich suche nach einer Standard-Spring-Implementierung, um zu vermeiden, dass ich meine eigene Rolle spiele. Gibt es einen anderen Spring-Konfigurator (oder irgendetwas anderes), um die Konfiguration zu initialisieren, oder sollte ich besser auf java config schauen, um dies zu erreichen?
Aktualisieren :
Basierend auf der Frage Update, ist mein Vorschlag:
ServiceResolver
-Bohne, die basierend auf der Clienteingabe alles behandelt, was Sie verarbeiten müssen; Der ServiceResolver
kann dann entweder auf dem init-method
oder bei jedem Aufruf die Werte bestimmen, die an den Client zurückgegeben werden, z. JNDI-Lookups oder Umgebungsvariablen.
Aber bevor Sie das tun, sollten Sie sich die Konfiguration ansehen Optionen verfügbar. Sie können entweder:
Wenn Sie Eigenschaften von einem benutzerdefinierten Ort aus suchen müssen, sehen Sie sich org.springframework.beans.factory.config.BeanFactoryPostProcessor
an und wie die org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
implementiert ist.
Die Grundidee ist, dass Sie die Bohnen mit den "rohen" Eigenschaften erhalten, z.B. ${jdbcDriverClassName}
und dann können Sie sie auflösen und durch die gewünschten Werte ersetzen.
Siehe Ссылка
%Vor%
TestClass.java
%Vor%
SpringStart.java
%Vor%
spring-config.xml
Ausgabe:
%Vor%
Meine bestehende Lösung beinhaltet das Definieren eines neuen MapAwareApplicationContext, der eine Map als zusätzliches Konstruktorargument verwendet.
%Vor%Es überschreibt postProcessBeanFactory (), um es einem MapAwareProcessor hinzuzufügen:
%Vor%Der MapAwareProcessor implementiert postProcessBeforeInitialization (), um die Map in einen beliebigen Typ einzufügen, der die MapAware-Schnittstelle implementiert:
%Vor%Ich füge dann eine neue Bean zu meiner Konfiguration hinzu, um einen MapAwarePropertyPlaceholderConfigurer zu deklarieren:
%Vor%Der Konfigurator implementiert MapAware, sodass die Map wie oben beschrieben injiziert wird. Anschließend implementiert es resolvePlaceholder (), um Eigenschaften aus der Zuordnung aufzulösen oder an den übergeordneten Konfigurator zu delegieren:
%Vor%PropertyPlaceholderConfigurer kann Eigenschaften aus einer Datei abrufen, das stimmt, aber wenn sie diese nicht finden können, greift sie auf die Systemeigenschaften zurück. Dies klingt nach einer praktikablen Option für Ihre Clientanwendung. Übergeben Sie die Systemeigenschaft einfach mit -D, wenn Sie den Client starten.
Aus dem javadoc
Ein Konfigurator prüft auch gegen Systemeigenschaften (z. B. "user.dir") wenn Es kann keinen Platzhalter mit lösen eine der angegebenen Eigenschaften. Dies kann über angepasst werden "systemPropertiesMode".
Erstellen Sie eine RmiProxyFactoryBean
-Instanz und konfigurieren Sie die Eigenschaft serviceUrl
direkt in Ihrem Code: