Posts tagged ‘xml’

Jakiś czas temu szukając informacji o szybkiej konfiguracji springa oraz połączeniu go z JAXB natrafiłem na blog Michała Mecha (strona Michała nie jest już dostępna – tekst w wayback machine)który to opisywał wspomniany przeze mnie problem.

Udało mi się w miarę sprawnie przenieść przykład, który zaprezentował na „własne podwórko” i zamiast wstrzykiwać do beana scieżkę do pliku który miałbyć zamieniony poprzez JAXB na obiekt, mogłem wstrzykiwać gotowy obiekt, a bean jak zwykle po prostu nie był swiadom skąd się ten obiekt wziął – z xml’a, czy może ktoś bo sobie „poskładał” łącząc odpowiednio pojo z mappingu xml’owego. Pojawił się tylko mały zgrzyt w momencie, gdy okazało się, że takich podmionionych bean’ów mam 40…

Zacząłem szukać jakiegoś sposobu aby uprościć konfigurację i zamknąć wszystko w jednej linijce i faktycznie udało się wykorzystując poszczególne elementy:

  • dodając do konfiga xml’owego przestrzeń nazw oxm
  • wykorzystując property editora
  • dodając element nadrzędny dla docelowego bean’a

Zmodyfikuje nieco oryginalny przykład w celu prezentacji rozwiązania:

Najpierw property editor w celu zamiany String’a na Source xml’owe:

package pl.bedkowski.test;

import java.beans.PropertyEditorSupport;
import java.io.File;

import javax.xml.transform.stream.StreamSource;

public class String2StreamSource extends PropertyEditorSupport {

	@Override
	public void setAsText(String filePath) {
		setValue(new StreamSource(new File(filePath)));
	}

}

No i kontekst apliacji:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:oxm="http://www.springframework.org/schema/oxm"

	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-1.5.xsd">

	<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
	  <property name="customEditors">
	    <map>
	      <entry key="javax.xml.transform.Source">
	        <bean class="pl.bedkowski.test.String2StreamSource"/>
	      </entry>
	    </map>
	  </property>
	</bean>

	<oxm:jaxb2-marshaller id="jaxb2Marshaller">
		<oxm:class-to-be-bound name="pl.michalmech.config.Config"/>
	</oxm:jaxb2-marshaller>

	<bean id="configParent"  class="pl.michalmech.config.Config" factory-bean="jaxb2Marshaller" factory-method="unmarshal" abstract="true" />

	<bean id="config1" parent="configParent">
		<constructor-arg value="config1.xml" />
	</bean>

	<bean id="config2" parent="configParent">
		<constructor-arg value="config2.xml" />
	</bean>

	<bean id="config3" parent="configParent">
		<constructor-arg value="config3.xml" />
	</bean>

	<bean id="config4" parent="configParent">
		<constructor-arg value="config4.xml" />
	</bean>

</beans>

Na początku może się wydawać, że to więcej jednak jeżeli odejmiemy te pare(-naście) linijek podczas każdej inicjalizacji bean’a dziedziczącego po „configParent”, podobnie do bean’ów z id’kami config1-config4.

Zdaję sobie sprawę, że dla niektórych ten wpis będzie równoznaczny z profanacją, ale ostatnio zastanawiałem się z której strony „ugryźć” problem przestawienia zależności w jednym projekcie na konfigurację spring’ową. Dlaczego – otóż nie miałem za bardzo pomysłu na zintegrowane rozwiązanie, obsługujące zależności w aplikacji w sposób kompleksowy, więc postanowiłem wybrać łatwiejsze rozwiązanie – wstawić xml’a, dorzucić jakiegoś prostego bean’a, a później to już pewnie jakoś pójdzie, no ale dobrze by było zacząć od początku.

Na pierwszy ogień wybrałem sobie plik konfiguracyjny. Poprzednia wersja aplikacji zawierała tekstowy plik konfiguracyjny w formacie zbliżonym do plików ini.

Na początek wyglądało to dość dobrze, bo trzeba było wpisać 2 rzeczy:

lista która to zawiera liste sekcji oddzielonych przecinkiem

– [sekcja1]

#ustawienia

[sekcja2]

#ustawienia

No i na pierwszy rzut oka to faktycznie ma sens, jednak po jakimś czasie okazało się, że to rozwiązanie dostarcza więcej problemów niż rozwiązuje a oto kilka z nich:

– zduplikowana konfiguracja – każde dodanie usunięcie sekcji wiązało się, z edycją wpisów w 2 miejscach

– mała elastyczność – zmiana opcji miejscami, w przypadku ich większej ilości to był koszmar

– małą czytelność w przypadku dużej liczby opcji

– brak wsparcia „ini with sections”  w javie – konieczność samodzielnego parsowania

No i zrodził sie pomysł zastąpienia tego xml’em springowym co w połączeniu z metodą getBeansOfType okazało się strzałem w dziesiątkę, tym bardziej, że opcje konfiguracyjne były już wczytywane do beana i dopiero później przekazywane dalej, więc jedyne co trzeba bylo zrobić to zdefiniować rodzica, podpiąć jary i już, oto przykład:


<!-- korzystam z <a href="http://static.springsource.org/spring/docs/2.0.x/reference/beans.html#beans-p-namespace">p namespace</a> -->

<beans>

<bean class="sample.Bean" id="parent" abstract="true" p:commonProperty="sampleValue" />

<bean id="bean1" parent="parent" p:property="jakas wlasnosc" />

</beans>