Ich arbeite an einer Anwendungsbibliothek mit einer Dienstprogrammklasse namens " Config
", die vom Objekt Spring Environment
unterstützt wird und stark typisierte Getter für alle Anwendungskonfigurationswerte bereitstellt.
Die Eigenschaftsquellen für die Konfiguration können je nach Umgebung (DEV / PROD) und Verwendung (standalone / test / webapp) variieren und können von den Standardquellen (System & amp; env) bis zu benutzerdefinierten Datenbanken und JNDI-Quellen reichen.
Was mich beschäftigt, ist, wie die Apps, die diese Bibliothek nutzen, die von Environment
verwendeten Eigenschaftenquellen leicht konfigurieren können, so dass die Eigenschaften für die Verwendung in unserer Config
-Klasse und über die% verfügbar sind. co_de%.
Wir verwenden immer noch die XML-Konfiguration, also könnte dies im Idealfall in XML konfiguriert werden.
%Vor%... und dann irgendwie in die Property-Quellensammlung der Umgebung eingefügt werden.
Ich habe gelesen, dass so etwas aufgrund des Timings des Lebenszyklus des App-Kontexts möglicherweise nicht möglich ist und dass dies möglicherweise mithilfe einer Initialisierungsklasse für Anwendungen geschehen muss.
Irgendwelche Ideen?
Ich habe folgendes gefunden, was zu funktionieren scheint, aber ich bin ziemlich neu bei Spring, daher bin ich mir nicht sicher, wie es unter verschiedenen Anwendungsfällen weitergehen wird.
Grundsätzlich besteht der Ansatz darin, PropertySourcesPlaceholderConfigurer
zu erweitern und einen Setter hinzuzufügen, damit der Benutzer eine Liste von PropertySource
-Objekten in XML einfach konfigurieren kann. Nach der Erstellung werden die Eigenschaftenquellen in das aktuelle Environment
kopiert.
Dies ermöglicht grundsätzlich, dass die Eigenschaftsquellen an einer Stelle konfiguriert werden können, aber von den Szenarien für die Plocholder-Konfiguration und Environment.getProperty verwendet werden.
Erweitert PropertySourcesPlaceholderConfigurer
beans.xml-Datei mit Basiskonfiguration
%Vor% Es hängt davon ab, wie Sie die Eigenschaften verwenden möchten, wenn die Eigenschaften mit der ${propertyname}
-Syntax injiziert werden sollen, dann funktioniert nur PropertySourcesPlaceHolderConfigurer, der intern Zugriff auf die in der Umgebung registrierten PropertySources hat.
Wenn Sie planen, Umgebung direkt zu verwenden, indem Sie env.getProperty()
verwenden, dann haben Sie Recht - die Eigenschaften, die PropertySourcesPlaceHolderConfigurer verwenden, sind hier nicht sichtbar. Der einzige Weg ist dann, es mit Java-Code zu injizieren, es gibt zwei Möglichkeiten, die ich kenne:
a. Verwenden von Java Config:
%Vor%b. Verwenden eines benutzerdefinierten ApplicationContextInitializer , wie es funktioniert ist hier
beschriebenDas Folgende funktionierte für mich mit Spring 3.2.4.
PropertySourcesPlaceholderConfigurer
muss statisch registriert werden, um die Platzhalter zu verarbeiten.
Die benutzerdefinierte Eigenschaftenquelle ist in der Methode init
registriert, und da die Standardeigenschaftsquellen bereits registriert sind, kann sie selbst mit Platzhaltern parametrisiert werden.
JavaConfig-Klasse:
%Vor%Benutzerdefinierte Eigenschaftenquelle:
%Vor% Test Bean ( getValue()
gibt "IT WORKS"
aus):
Ich hatte ein ähnliches Problem, in meinem Fall verwende ich Spring
in einer eigenständigen Anwendung, nach dem Laden der Standardkonfigurationen muss ich möglicherweise eine andere Eigenschaftendatei (lazy load configs) in einem Konfigurationsverzeichnis anwenden. Meine Lösung war inspiriert von dieser Spring Boot
Dokumentation , aber ohne Abhängigkeit von Spring Boot
. Siehe unten den Quellcode:
Ich bin kürzlich auf das Problem eingegangen, wie benutzerdefinierte Property-Quellen in der Umgebung registriert werden. Mein spezifisches Problem ist, dass ich eine Bibliothek mit einer Spring-Konfiguration habe, die ich in den Spring-Anwendungskontext importieren möchte, und dass benutzerdefinierte Eigenschaftsquellen erforderlich sind. Ich habe jedoch nicht unbedingt die Kontrolle über alle Orte, an denen der Anwendungskontext erstellt wird. Aus diesem Grund möchte ich die empfohlenen Mechanismen von ApplicationContextInitializer oder register-before-refresh nicht verwenden, um die benutzerdefinierten Eigenschaftsquellen zu registrieren.
Was ich wirklich frustrierend fand, war, dass mit der alten PropertyPlaceholderConfigurer die Unterkonfigoren innerhalb der Spring-Konfiguration leicht unterklassifiziert und angepasst werden konnten. Um Eigenschaftsquellen anzupassen, wird uns dagegen gesagt, dass wir dies nicht in der Spring-Konfiguration selbst tun müssen, sondern bevor der Anwendungskontext initialisiert wird.
Nach einigen Nachforschungen und Versuchen habe ich festgestellt, dass es möglich ist, benutzerdefinierte Property-Quellen innerhalb der Spring-Konfiguration zu registrieren, aber Sie müssen aufpassen, wie Sie es tun. Die Quellen müssen registriert werden, bevor PropertySourcesPlaceholderConfigurers im Kontext ausgeführt werden können. Sie können dies tun, indem Sie die Quellenregistrierung zu einem BeanFactoryPostProcessor mit PriorityOrdered und einer Reihenfolge mit höherer Priorität als PropertySourcesPlaceholderConfigurer machen, die die Quellen verwendet.
Ich habe diese Klasse geschrieben, die den Job erledigt:
%Vor%Beachten Sie, dass die Standardreihenfolge dieser Factory-Klasse der Eigenschaftenquelle eine höhere Priorität hat als die Standardreihenfolge von PropertySourcesPlaceholderConfigurer.
Auch die Registrierung der Eigenschaftenquelle erfolgt in postProcessBeanFactory, was bedeutet, dass sie in der richtigen Reihenfolge relativ zu PropertySourcesPlaceholderConfigurer ausgeführt wird. Ich entdeckte die harte Art, dass InitializingBean und afterPropertiesSet den Befehlsparameter nicht respektieren, und ich gab diesen Ansatz als falsch und redundant auf.
Schließlich, weil dies ein BeanFactoryPostProcessor ist, ist es eine schlechte Idee, zu versuchen, viel in der Art von Abhängigkeiten zu verbinden. Daher greift die Klasse direkt auf die Umgebung über den Anwendungskontext zu, den sie mit ApplicationContextAware erhält.
In meinem Fall benötigte ich die Eigenschaft source, um Passworteigenschaften zu entschlüsseln, die ich mit der folgenden Unterklasse implementiert habe:
%Vor%Schließlich habe ich die Property Source Factory in meiner Spring-Konfiguration angegeben:
%Vor%Um ehrlich zu sein, ist es bei den Standardeinstellungen für die Reihenfolge in PropertySourcesPlaceholderConfigurer und AbstractPropertySourceFactory wahrscheinlich nicht einmal notwendig, die Reihenfolge in der Spring-Konfiguration anzugeben.
Nichtsdestoweniger funktioniert das, und es erfordert nicht , sich mit der Initialisierung des Anwendungskontexts herumzuärgern.
Tags und Links spring