Pliki *.properties w Spring Framework 3
Zdecydowana większość projektów, w których miałem okazję brać udział jako programista, opierała się na Spring Framework. Myślą przewodnią, która przyświecała twórcom tego cuda było przede wszystkim to, aby uprościć te rzeczy, co do których nie ma powodu, aby były skomplikowane. I jedną z takich rzeczy jest na pewno przechowywanie ustawień w plikach *.properties.
I znowu sytuacja z plikami *.properties nie jest w Javie tak prosta, jakby to się mogło na pierwszy rzut oka wydawać. Pomijając już kwestie samego wczytania takiego pliku (na przykład do klasy Properites) zwłaszcza w aplikacji webowej, dochodzi jeszcze kwestia kodowania, istotna z powodu częstego wykorzystywania w/w plików do tłumaczeń. Pomimo tego, że źródła możemy mieć w UTF-8, propertiesy zgodnie ze standardem zawsze kodowane są w ISO 8859-1. Chociaż może być to uciążliwe (ale nie z Eclipse razem z odpowiednim pluginem - polecam!), ma to sporo sensu i gwarantuje, że żaden nowy programista z błędnym kodowaniem projektu nie doda nam śmieci w postaci kwadracików i gwiazdek do repozytorium.
No ale powróćmy do samego Springa. Nie jest nowością wykorzystywanie ustawień z propertiesów w springowym xml-u i wstrzykiwanie ich do beanów. Można to zrobić mniej więcej tak:
<context:property-placeholder location="classpath:settings.properties" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
Pewien kłopot zaczyna się, kiedy chcemy pozbyć się wszechobecnego xml-a (a chcemy, prawda?) i używać adnotacji. Do tej pory nie można było wykorzystać beana, który wczytywał propertiesy (jest to zresztą obiekt klasy PropertyPlaceholderConfigurer), aby w stworzonych przez nas ziarnach springowych do takich ustawień prosto się dostać. Sytuacja kończyła się zwykle tym, że powstawał jakiś ConfigurationService, który poza Springiem (bądź też wykorzystując niektóre jego niskopoziomowe mechanizmy) wczytywał dane z pliku (bądź plików) *.properties, a sam był wstrzykiwany wszędzie tam, gdzie potrzebny był dostęp do tychże ustawień.
Można spytać, czy nie da się tego zrobić prościej. Otóż w Spring Framework 3.0 jak najbardziej jest to możliwe dzięki adnotacji @Value. Wystarczy użyć następującej konstrukcji:
@Value("${admin.email}")
private String adminEmail;
Pewne zamieszanie może być związane z tym, że jednocześnie w nowej wersji Springa wprowadzono expression language, który również może być wykorzystywany w xml-u czy w adnotacjach. Kawałek kodu, który wkleiłem powyżej z dobrodziejstwa springowego EL nie korzysta, poniższy natomiast już jak najbardziej:
<util:properties id="settings" location="classpath:settings.properties"/>
@Value("#{settings.adminEmail}")
private String adminEmail1;
@Value("#{settings.admin.email}")
private String adminEmail12;
Różnica jest znaczna, chociaż teoretycznie występuje w jednym znaczku, tzn. w #. Jest to jednak zupełnie odmienna konstrukcja, której spore możliwości można dokładniej poznać przeglądając dokumentację. Warto jednak zauważyć, że jedynie zmienna adminEmail1 zostanie ustawiona, o ile w naszym pliku settings.properties znajdziemy wartość dla klucza adminEmail. Do zmiennej adminEmail2 byłaby wstrzyknięta wartość jedynie wtedy, jeśli admin byłoby obiektem z atrybutem email, a wiemy, że tak nie jest.
Jeśli zaś chodzi przykłady, gdzie Spring-EL się naprawdę przydaje, to kolejny raz odsyłam do wpisu o najnowszym Spring Security, warto zobaczyć jakie nowości udostępnia nam kolejna wersja tej biblioteki.





