Blog

Konfigurieren Sie Ihre externen Abhängigkeiten mit Spring & Jndi

Aktualisiert Oktober 23, 2025
4 Minuten
Wie geht man mit plattformspezifischen Variablen in Java-Anwendungen um (Test, Abnahme, Produktion usw.)? Anwendungen benötigen häufig Ressourcen wie Datenbanken, Webservices von Drittanbietern, ldap-Server und andere externe Systeme. Es ist gängige Praxis, die Konfiguration solcher Ressourcen auszulagern. Im Falle einer Datenbankabhängigkeit ist die Verwendung einer DataSource (die die Komplexität der Konfiguration und Verbindung zur Datenbank verbirgt) ein gutes Beispiel dafür. Die Details der Konfiguration sind in den meisten Fällen plattformspezifisch. Wie können wir also die Details der Konfiguration richtig auslagern? Im Grunde hat das Entwicklungsteam zwei Möglichkeiten:
  • Erstellen Sie eine Anwendung und geben Sie die Zielumgebung an
  • Externalisieren Sie die Variablen aus der einsatzfähigen Einheit
Ich habe gesehen, dass viele Entwicklerteams die erste Option verwenden. Sie verwenden ant, maven oder maven2, um ihre Java-Anwendung zu erstellen, und sie verwenden einen Befehlsparameter, um die Zielumgebung des Builds anzugeben. Normalerweise sieht das in etwa so aus: [code]$ ant install -Denv=test[/code] oder im Falle von maven2 über Profile: [code]$ mvn -P test clean install[/code] Es gibt zahlreiche Möglichkeiten, dies mit Hilfe von Eigenschaftsdateien, xml-Deskriptoren, Filterung usw. zu erreichen. Das Endergebnis ist eine einsatzfähige Einheit, die nur in der Umgebung eingesetzt werden kann, für die sie erstellt wurde. Ich mag diesen Ansatz nicht. Es ist besser, eine einsatzfähige Einheit zu haben, die in jeder Umgebung eingesetzt werden kann. Das liegt vor allem daran, dass die Bereitstellung einer Anwendung nicht in der Verantwortung der Entwickler liegen sollte. Sie liegt in der Verantwortung der Wartungsabteilung und die umgebungsspezifischen Variablen sollten Teil der Umgebung und nicht der Anwendung sein. Das letzte Argument ist, dass die Entwickler oft keine Kenntnisse über die Ressourcen der Akzeptanz- oder Produktionsumgebung haben. Wie können sie zum Beispiel den Benutzernamen und das Passwort der Produktionsdatenbank kennen? Wie können wir also die einsatzfähige Einheit unabhängig von der Zielumgebung machen? Zunächst müssen wir sicherstellen, dass wir keine umgebungsspezifischen Werte in der Codebasis fest einprogrammieren. Dies ist, abgesehen von dem Problem, mit dem wir es zu tun haben, immer eine gute Praxis. Wir verwenden also Eigenschaftsdateien oder noch besser (wenn Sie Spring verwenden, und das sollten Sie!) wir verwenden Platzhalter in unseren Anwendungskontextdateien. Ein Beispiel: Wir verwenden einen LDAP-Server zur Authentifizierung unserer Benutzer in Kombination mit dem hervorragenden Acegi-Framework. Nehmen wir an, wir haben einen Test-LDAP-Server und einen Produktions-LDAP-Server. [xml] [/xml] Spring bietet bereits Unterstützung für die Auflösung von Platzhaltern wie ${ldap_address} während der Laufzeitinitialisierung der Bean Factory. Definieren Sie einfach einen PropertyPlaceholderConfigurer in Ihrer Anwendungskontextdatei, der eine Properties-Datei verwendet, um Werte in Bean-Definitionen zu ziehen. Das Problem bei diesem Ansatz ist jedoch, dass Sie den PropertyPlaceholderConfigurer mit dem Speicherort der Eigenschaftsdatei verdrahten müssen. Der Entwickler kann keine Annahmen über den Speicherort der Eigenschaftsdatei machen, und es ist auch nicht ratsam, dies zu tun. Es wäre schön, wenn wir eine generische Möglichkeit hätten, einen PropertyPlaceholderConfigurer mit den richtigen Werten zu verdrahten. Hier kommt Jndi ins Spiel! Wenn Sie einen generischen Hook hätten, um die Umgebung des InitialContext mit den Werten der Platzhalter zu füllen, könnten wir den Jndi-Kontext verwenden, um die spezifischen Platzhalter zu suchen und aufzulösen. Die meisten Anwendungsserver verfügen über einen solchen Hook und ich zeige Ihnen, wie Sie dies mit dem ausgezeichneten JBoss Application Server bewerkstelligen können. Mit der Datei jndi.properties im conf-Verzeichnis Ihrer Serverkonfiguration können Sie die plattformspezifischen Umgebungswerte ganz einfach an den InitialContext übergeben. Wenn Sie die Datei jndi.properties verwenden, müssen Sie keinen absoluten oder relativen Pfad in Ihrem PropertyPlaceholderConfigurer fest einprogrammieren. Um unser Beispiel fortzusetzen, benötigen wir den folgenden Schlüssel-Wert-Eintrag für unsere initialDirContextFactory-Bean: [code]ldap_address=ldap://organization.intra.local.test[/code] Fügen Sie dieses Schlüssel-Wert-Paar der Datei jndi.properties im Verzeichnis conf Ihrer JBoss-Serverkonfiguration hinzu und verwenden Sie einen angepassten PropertyPlaceholderConfigurer, um Ihre Platzhalter aufzulösen: [java] public class JndiPlaceholderConfigurer extends PropertyPlaceholderConfigurer implements InitializingBean { private Map environment; public void afterPropertiesSet() throws Exception { Context context = new InitialContext(); environment = context.getEnvironment(); } protected String resolvePlaceholder(String placeholder, Properties props) { return (String) this.environment.get(placeholder); } } [/java] Mit einer Zeile xml-Code in einer Ihrer Spring Bean-Definitionsdateien wird die Nachbearbeitung der BeanFactory-Initialisierung die Auflösung der Platzhalter übernehmen: [xml] [/xml] Natürlich müssen Sie ein geeignetes Verfahren einrichten, um die umgebungsspezifischen Variablen, von denen Ihre Anwendung abhängt, an die Person/Abteilung zu übermitteln, die für die Bereitstellung der Anwendung verantwortlich ist. Derzeit beschäftige ich mich mit dem Assembly-Plugin für Maven 2, um den Prozess der Bereitstellung von mehr als nur der einsatzfähigen Anwendungseinheit an die für die Bereitstellung von Anwendungen zuständigen Personen zu automatisieren. In meinem nächsten Blog werde ich mehr über das Assembly-Plugin erfahren und wie Sie sicherstellen, dass die Konfiguration des Anwendungsservers den Anforderungen Ihrer Anwendung entspricht.

Contact

Let’s discuss how we can support your journey.