Spring PropertyPlaceHolder

Hallo,

bei über die Oberfläche konfigurierbaren persistenten Einstellungen bietet sich in der Regel ein mehrstufiger Konfigurationsmechanismus an.

Dabei kann es mehrere (zwischen) Ebenen geben z.bsp.:

Relevanz) Ausprägung)
1) Direkt im Code (defaults)
2) Konfigurationsdatei (noch mehr defaults)
3) Customer-Konfigurationsdatei
4) JVM Properties -Dde.tutorials.Services.someProperty=value

Dabei überschreiben Werte mit höherer Relevanz Werte mit niedriger Relevanz.

Beispiel:
Wir haben 3 Konfigurierbare Optionen:
A, B und C
Ihre Defaultwerte im Code (1): A=1000, B =50, C=-1

Zusatzlich finden sich in einer zusätzlichen Konfigurationsdatei (2)
Noch folgende Werte fuer die Optionen B und C: B = 1111 und C = 21

Ausserdem wird der Anwendung noch der Umgebungsparameter (4) -Dde.tutorials.SomeObject.c=42 uebergeben.

Die effektive Konfiguration ergibt nun:
A=1000
B=1111
C=42

Das Ganze lässt sich dann über ein wenig ReflectionMagic realisieren.
Zu vollen Qualifizierung der jeweiligen Optionen bieten sich der FQCN + der Name des Attributs an.

Ich denke man sollte Spring eher in diese Richtung erweitern als das durch irgendwelche Hacks mit der aktuellen Version zu handeln.

Gruß Tom
 
Hi,

super. Danke für die Tipps und Beispiele. Werde ich auf jeden Fall mal ausprobieren wenn ich von der Arbeit zurück bin.

Gruß,
Ingo
 
@Tom: Ich versteh zwar nicht, warum der AC refresh sein muss, aber okay... Mit Property A überschreibt Property B überschreibt Property C oder anders herum hab ich auch etwas meine Probleme. Sowas klingt zwar beim Prototyping nice, bringt aber im Betrieb und in der Wartung nur Stress. Lass da mal wen unbedarftes (Admins) dran und lass die rausfinden warum jetzt Wert X zur Laufzeit auftaucht.

Ich denk, die einfache Variante sollte den Anfang machen... das ist quasi KISS (Keep It Simple and Stupid) und YAGNI (You Ain't Gonna Need It) vereint ;)

REINHAUN!
 
Hallo,

CAC.refresh() war notwendig, da die Property Placeholder Informationen scheinbar gecached werden. Durch ein explizites refresh() werden die Properties wieder neue eingelesen (scheint zumindest so...)

Gruß Tom
 
Ruf die Setter auf der DataSource und gut ist. Davon muss doch der PPC nix wissen. Das ist eh nur ein BeanFactoryPostProcessor. Nachdem die Beans instantiiert wurden ist der weg vom Fenster. Und wegen 4 Strings gleich nen kompletten AC neu hochziehen? ;)

REINHAUN!
 
So,

erst einmal nochmal Danke für die Tipps. So weit funktioniert das alles. Allerdings habe ich große Probleme bei der Angabe der Location in der Spring Konfig...

Folgendes Problem:
Bei der Entwicklung und Testen der RCP Anwendung findet Spring keine Dateien die nicht im Classpath sind oder vollständig sprich absolut angegeben sind.

Beim Start der Anwendung überprüfe vor Erstellung des Spring Applikation Contexts ob die property file vorhanden ist, falls nein kopiere ich eine mit dem Default-Settings aus Classpath ins File-System.
Code:
public void start(final BundleContext context) throws Exception {
		super.start(context);
		plugin = this;
		FileHelper.createPropertyFile("properties/xxx.prefs");
		this.applicationContext = createApplicationContext();
	}
   

   public static void createPropertyFile(String propertyFile) throws IOException {
		//IPath filePath = Platform.getLocation();
		IPath filePath = new Path(Platform.getInstallLocation().getURL().getPath());
		filePath = filePath.append(propertyFile);

		if (!filePath.toFile().exists()) {
			// check if dir exists
			File dir = filePath.removeLastSegments(1).toFile();
			if (!dir.exists()) {
				dir.mkdirs();
			}

			
			InputStream fis = FileLocator.openStream(Activator.getDefault()
					.getBundle(), new Path(propertyFile), false);
			FileOutputStream fos = new FileOutputStream(filePath.toFile());
			try {
				byte[] buf = new byte[1024];
				int i = 0;
				while ((i = fis.read(buf)) != -1) {
					fos.write(buf, 0, i);
				}
			} catch (IOException e) {
				throw e;
			} finally {
				if (fis != null)
					fis.close();
				if (fos != null)
					fos.close();
			}
		}
	}


Frage ist nur wie verweise ich in der Spring-Konfig nun auf diesen Pfad. So findet Spring die Konfig nicht, vor allem nicht wenn ich in Eclipse teste...

Code:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
		<property name="location" value="file:properties/xxx.prefs" />
	</bean>

Deshalb meine Frage: Wie kann ich die INI Datei richtig auslagern, sprich, außerhalb des ClassPaths?

Ich hoffe ihr könnt mir weiterhelfen.

Gruß,
Ingo
 
Zurück