Praktyczna Java. Aplikacje webowe ze Springiem bez XMLa

By 9 July 2016 Praktyczna Java

W naszym kur­sie Javy część kon­fig­u­racji jest w postaci plików XML — jest to nadal sposób, z którym moż­na się częs­to spotkać w różnych sys­temach. Tworząc nową aplikac­je są jed­nak wygod­niejsze pode­jś­cia, o których będzie ten wpis.

Kon­fig­u­rac­ja XML początkowo była stan­dar­d­em w przy­pad­ku Springa — pomi­mo alter­naty­wnych możli­woś­ci, które ist­ni­ały już dawno temu, nie pozwalały one na to samo, na co pozwalały stare dobre pli­ki XML. Na szczęś­cie sytu­ac­ja zmieniła się z cza­sem i obec­nie możli­wa jest peł­na kon­fig­u­rac­ja z uży­ciem adnotacji.

W tej kwestii zda­nia są nadal podzielone — zde­cy­dowana więk­szość prefer­u­je jed­nak kon­fig­u­rację za pomocą adno­tacji. Dzię­ki temu może­my wyko­rzys­tać pełne możli­woś­ci naszego środowiska IDE w zakre­sie anal­izy skład­ni, wyszuki­wa­nia uży­cia, odniesień do klas itp. Dodatkowo nie wyma­ga zna­jo­moś­ci tagów specy­ficznych dla Springa — całość kon­fig­u­racji odby­wa się za pomocą języ­ka Java, co jest też ułatwie­niem dla osób dopiero zaczy­na­ją­cych kari­erę w branży IT.

Pozbywamy się pliku application-context.xml

W naszych lekc­jach korzys­tal­iśmy z dość min­i­mal­isty­cznego pliku application-context.xml — służył on nam właś­ci­wie wyłacznie do inicjowa­nia Spring’a i kon­fig­u­racji skanowa­nia paki­etów. Pokaże­my, jak zamieni­ać poszczególne jego ele­men­ty na kon­fig­u­rację z uży­ciem języ­ka Java

Uwa­ga! W tej opcji nadal niezbęd­ny jest plik web.xml, który służy do uruchami­a­nia aplikacji webowej — o tym, jak i jego może­my się pozbyć, czy­taj dalej.

Zmiany w pliku web.xml

Pier­wszym krok­iem jest utworze­nie klasy z adno­tacją @Configuration oraz zmi­ana w pliku web.xml. Póki co stworzymy puste klasy:

@Configuration
public class SpringRootConfiguration {

}
@Configuration
public class SpringMvcConfiguration {

}

a następ­nie zamien­imy obec­ny plik web.xml (z lekcji 9 naszego kur­su Javy):

<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>Baza danych kotow</display-name>

    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/rootApplicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

na następu­ją­cy:

<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>Baza danych kotow</display-name>

    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>pl.kobietydokodu.spring.SpringMvcConfiguration</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>pl.kobietydokodu.spring.SpringRootConfiguration</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

Zwróć uwagę, że dodal­iśmy para­metr con­textClass — dzię­ki temu mogliśmy zamienić domyśl­ny Xml­We­bAp­pli­ca­tion­Con­text na Anno­ta­tion­Con­fig­We­bAp­pli­ca­tion­Con­text (czyli z takiego, który bazu­je na kon­fig­u­racji XML-owej na nowszy, bazu­ją­cy na adno­tac­jach). Możesz w tym momen­cie spróbować uru­chomić aplikację — najpraw­dopodob­niej nie zadzi­ała tak jak byś chci­ała, ponieważ nie prze­nieśliśmy jeszcze kon­fig­u­racji z plików XML do naszych klas, czym się ter­az zajmiemy.

Konfiguracja skanowania pakietów

Skanowanie paki­etów może­my uzyskać za pomocą adno­tacji @ComponentScan. Kon­fig­u­rac­je XML:

<context:component-scan base-package="pl.kobietydokodu.pakiet,pl.kobietydokodu.inny" />

może­my zamienić na następującą:

@ComponentScan(basePackages = {"pl.kobietydokodu.pakiet","pl.kobietydokodu.inny"})
@Configuration
public class SpringConfig {

}

Uwa­ga: jeśli nie podamy żad­nych paki­etów (uży­je­my po pros­tu @ComponentScan bez żad­nych para­metrów), skanowanie rozpocznie się od bieżącego paki­et (tzn tego, w którym zna­j­du­je się klasa z tą adno­tacją) — przeskanowane zostaną także wszys­tkie paki­ety ‘podrzędne’ do obecnego.

Deklarowanie beanów

Deklarowanie beanów w XML‑u wyglą­dało następujaco:

<bean id="someService" class="pl.kobietydokodu.SomeService" init-method="init">
    <property name="someDependency" ref="someDependencyImpl" />
</bean>

W przy­pad­ku kon­fig­u­racji w Javie musimy samodziel­nie stworzyć dany obiekt — prob­le­mem z tym pode­jś­ciem mogą być pola, które nie mają set­terów (i nie są możli­we do ustaw­ienia przez kon­struk­tor), ani adno­tacji @Autowired (lub ana­log­icznej). Dlat­ego ta zmi­ana kon­fig­u­racji może wyma­gać delikat­nych zmi­an w klasach (lub uży­cia reflek­sji, co jest nieza­le­cane). W pod­sta­wowej wer­sji powyższa kon­fig­u­rac­ja wyglą­dała­by następująco:

@Configuration
public class SpringConfig {
    @Autowired
    @Qualifier("someDependencyImpl")
    private SomeDependency someDependency;

    @Bean(name="someService", initMethod="init")
    public SomeService someService {
        SomeService service = new SomeService();
        service.setSomeDependency(someDependency);
        return service;
    }

}

Jak widzisz pier­wsza waż­na zmi­ana to to, że zależnoś­ci (do których w XMLu odnosil­iśmy się poprzez atry­but ‘ref’) ter­az musimy ‘pobrać’ (poprzez utworze­nie pola i dodanie adno­tacji @Autowired) a następ­nie ręcznie wstrzyknąć je do klasy (o ile nie ma ona adno­tacji @Autowired nad swoi­mi pola­mi). Bezpośred­nim odpowied­nikiem atry­bu­tu ref jest adno­tac­ja @Qualifier — pozwala podać id (lub nazwę) beana, który chce­my w tym miejs­cu ‘pobrać’.

Różni­ca pomiędzy id oraz name wys­tępu­je tylko w XML i jest czys­to teo­re­ty­cz­na — z uwa­gi na skład­nie XML, ele­ment może mieć wyłącznie jed­no id, nie wszys­tkie zna­ki są doz­wolone. Bean w Springu może mieć wiele nazw, które są funkcjon­al­nie tym samym co id — są po pros­tu mniej restryk­cyjne. Kon­fig­u­rac­ja za pomocą adno­tacji nie rozróż­nia pomiędzy id oraz name (możli­we jest ustaw­ie­nie wyłącznie name — jed­nego lub wielu).

Konfiguracja MVC

W kon­fig­u­racji XML za ‘włącze­nie’ adno­tacji i obsłu­gi MVC odpowiadał fragment:

<mvc:annotation-driven />

Ana­log­iczny efekt może­my uzyskać doda­jąc do naszej kon­fig­u­racji adno­tację @EnableWebMvc:

@Configuration
@EnableWebMvc
public class SpringConfig {

}

Jeśli potrze­bu­je­my dodatkowej kon­fig­u­racji mod­ułu MVC (np. jeśli chcesz dodać obsługę staty­cznych plików), klasa kon­fig­u­racji może dziedz­iczyć po Web­Mvc­Config­ur­erAdapter oraz nad­pisać stosowne metody (przykład dla obsłu­gi staty­cznych plików):

@Configuration
@EnableWebMvc
public class SpringConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
            .addResourceHandler("/css/**/*")
            .addResourceLocations("/WEB-INF/static/css/");
    }
}

Oczy­wiś­cie możesz nad­pisać inne metody, aby zmody­fikować inne aspek­ty Spring­MVC (np. dodać inter­cep­to­ry zapy­tań czy zmienić sposób mapowa­nia adresów URL lub dodać własne Validatory).

Konfiguracja (i pliki .properties)

Kon­fig­u­rac­ja XML wyma­gała jedynie jed­nej linijki:

<context:property-placeholder location=“classpath:configuration.properties” />

W przy­pad­ku kon­fig­u­racji w Javie wyma­gane są dwa kro­ki — musimy dodać adno­tację @PropertySource oraz stworzyć beana typu Prop­er­tySource­s­Place­hold­er­Con­fig­ur­er. Sama adno­tac­ja jedynie pobiera wartoś­ci z pliku .prop­er­ty oraz pozwala się do nich dostać poprzez inter­fe­js Envi­ron­ment. Bean pozwala na uży­wanie tych wartoś­ci np. w połącze­niu z adno­tacją @Value, stąd w więk­szoś­ci przy­pad­ków jest ona potrzebna.

@Configuration
@PropertySource("classpath:configuration.properties")
public class SpringConfig {
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

Jeśli potrze­bu­je­my zare­je­strować więk­szą ilość plików .prop­er­ty, wystar­czy powielić adno­tację poda­jąc ścieżkę do każdego pliku osobno.

Importowanie innych konfiguracji

XMLe pozwalały nam dołączać inne pli­ki kon­fig­u­racji za pomocą tagu <import … /> . W przy­pad­ku kon­fig­u­racji za pomocą adno­tacji są trzy sposo­by na dołącze­nie innych konfiguracji:

Skanowanie pakietów

Jeśli kon­fig­u­rac­ja, którą chce­my dołączyć, zna­j­du­je się w jed­nym z paki­etów skanowanych przez Springa (patrz wyżej, jak skon­fig­urować skanowanie), to nie musimy robić nic więcej — Spring sam ‘odkry­je’ te klasy i odpowied­nio je skonfiguruje.

Dołączanie klas konfiguracji

Jeśli chce­my dołączyć klasę, która nie jest ‘wykry­wana’ przez Springa pod­czas skanowa­nia paki­etów, może­my użyć adno­tacji @Import:

@Configuration
@Import(OtherConfig.class)
public class SpringConfig {
}

Dołączanie konfiguracji XML

Cza­sem z różnych powodów konieczne jest dołącze­nie kon­fig­u­racji w postaci pliku XML, w tym wypad­ku może­my posłużyć się adno­tacją @ImportResource:

@Configuration
@ImportResource("classpath:/spring-config/legacy.xml")
public class SpringConfig {
}

Sprzątanie

Po wszys­tkim warto uporząd­kować pli­ki pro­jek­tu — ponieważ pli­ki XML z kon­fig­u­racją nie są nam już potrzeb­ne, może­my je w tym momen­cie całkowicie usunąć.

Pozbywamy się pliku web.xml

W tym momen­cie w naszej aplikacji pozbyliśmy się kon­fig­u­racji Springa w XMLu — został jeszcze plik web.xml. Od Servlet API 3.0 możli­we jest pozby­cie się i tego pliku oraz kon­fig­u­rac­ja aplikacji czys­to Javowa. Ważne jest jed­nak, aby upewnić się, że nasz ser­w­er aplikacji wspiera Servlet API w odpowied­niej wer­sji, np. dla Tom­ca­ta wspar­cie jest ofer­owane od wer­sji 7.0. Dla innych ser­w­erów aplikacji bez prob­le­mu zna­jdziesz podob­ne zestaw­ie­nie — przed wprowadzaniem poniższych zmi­an, upewnij się, że Two­ja kon­fig­u­rac­ja będzie dzi­ałała po zmianach.

Zamieniamy plik web.xml

Jako bazę do zmi­an wyko­rzys­tamy zmody­fikowany plik web.xml przy­toc­zony w sekcji powyżej. Uruchamia on dwa kon­tek­sty Springa, w tym jeden ‘główny’ i jeden pow­iązany z Servletem.

Aby stworzyć kon­fig­u­rację odpowiada­jącą web.xml, musisz utworzyć nową klasę, która imple­men­tu­je inter­fe­js WebAp­pli­ca­tion­Ini­tial­iz­er oraz przesłonić metodę onStartup:

public class SpringWebsiteInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext container) {

    }
}

Taka klasa oczy­wiś­cie nic jeszcze nie robi, ale możesz zwery­fikować (np. debug­gerem lub wyp­isu­jąc jak­iś tekst do logu), że fak­ty­cznie jest ona uruchami­ana. Kole­jnym krok­iem jest dodanie kon­fig­u­racji DispatcherServlet:

public class SpringWebsiteInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext container) {
        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(SpringWebConfig.class);

        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}

Uwa­ga: możli­we jest także sko­rzys­tanie z kon­fig­u­racji XML — koniecz­na jest wtedy zami­ana Anno­ta­tion­Con­fig­We­bAp­pli­ca­tion­Con­text na Xml­We­bAp­pli­ca­tion­Con­text (przykład uży­cia zna­jdziesz w doku­men­tacji inter­fe­j­su WebAp­pli­ca­tion­Ini­tial­iz­er).

Ta kon­fig­u­rac­ja odpowia­da stosownym para­metrom w pliku web.xml — zwróć uwagę, że w tym wypad­ku nie było konieczne osob­ne określanie klasy, aby umożli­wić kon­fig­u­rac­je z uży­ciem adno­tacji — dzię­ki temu, że ope­ru­je­my na obiek­tach, wystar­czy stworzyć obiekt odpowied­niego typu (w tym wypad­ku AnnotationConfigWebApplicationContext).

Zwróć także uwagę na wywołanie dispatcherContext.register(…) — ta meto­da po pros­tu doda­je do kon­tek­stu nowego beana. Jeśli chcesz, możesz dodać pozostałe pli­ki kon­fig­u­racji w tym miejs­cu (choć zale­camy ‘łącze­nie’ ich już na poziomie samych klas kon­fig­u­racji jak zostało to opisane wyżej, a nie tworząc kontekst).

Ostat­nim krok­iem jest dodanie także ‘głównego’ kon­tek­stu, po czym nasza klasa będzie wyglą­dała następująco:

public class SpringWebsiteInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext container) {
        //główny kontekst
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(SpringRootConfig.class);
        container.addListener(new ContextLoaderListener(rootContext));

        //kontekst Servletu
        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(SpringWebConfig.class);
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}

Jeszcze prościej

Powyższy opis obrazu­je jak moż­na skon­fig­urować Springa ‘ręcznie’ — sam Spring zapew­nia kil­ka klas, które jeszcze bardziej upraszcza­ją kon­fig­u­rację. Jeśli mamy domyśl­ną kon­fig­u­rację, z dwoma kon­tek­sta­mi i jed­nym Servletem, są one lep­szym rozwiązaniem. W prze­ci­wnym razie najpraw­dopodob­niej będziesz musi­ała sko­rzys­tać z opcji powyżej.

Uproszc­zona kon­fig­u­rac­ja sprowadza się do dziedz­iczenia po klasie Abstrac­tAn­no­ta­tion­Con­figDis­patch­erServle­tIni­tial­iz­er (uwa­ga: klasa ta dostęp­na jest dopiero od Springa 3.2 w odróżnie­niu do opisanych wcześniej rozwiązań!) oraz imple­men­tacji kilku metod (zwraca­ją­cych jedynie proste para­me­try konfiguracyjne):

public class SpringInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {SpringRootConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] {SpringMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

Jak sama widzisz, ta kon­fig­u­rac­ja jest jeszcze prost­sza i dużo czytel­niejsza niż web.xml :)

Ważne — sprzątanie!

Uwa­ga! Opisana powyżej kon­fig­u­rac­ja oraz plik web.xml nie wyk­lucza­ją się wza­jem­nie! Tzn. jeśli nie ska­su­jesz pliku web.xml po doko­na­niu powyższych zmi­an, Two­ja aplikac­ja będzie uruchami­ała dwie aplikac­je — w zależnoś­ci od ustaw­ień może to spowodować błąd, ale może też nie być widoczne od razu i prowadz­ić do ‚dzi­wnych’ błędów w aplikacji. Dlat­ego pamię­taj, aby po doko­na­niu zmi­an usunąć plik web.xml

Spring Boot

Alter­naty­wną opcją do powyższych jest sko­rzys­tanie z bib­liote­ki Spring Boot — bib­liote­ka ta nieco upraszcza tworze­nie aplikacji w Springu i jeśli nie jest prob­le­mem dołącze­nie nowych zależnoś­ci do pro­jek­tu, warto ją rozważyć. Różni­ca w przy­pad­ku Spring Boot pole­ga na tym, że nie potrze­bu­je­my imple­men­tować WebApplicationInitializer’a — wystar­czy adno­tac­ja @SpringBootApplication oraz pros­ta meto­da main — dzię­ki temu może­my uruchami­ać aplikację także poprzez zwykłe ‚Run as -> Java Application’.

Poza brakiem pliku web.xml oraz pow­iązanej z tym kon­fig­u­racji, tworze­nie czy rozwi­janie aplikacji z uży­ciem Spring­Boot niczym nie różni się od zwykłej aplikacji w Spring­MVC — sposób przenoszenia kon­fig­u­racji z XML do Javy czy korzys­ta­nia z funkcji Springa jest dokład­nie taki sam (Spring­Boot ofer­u­je głównie ułatwie­nie w kwestii kon­fig­u­racji i uruchami­a­nia, a nie mody­fiku­je samego bazowego frame­wor­ka — ma więc wpływ głównie na devel­op­ment, a nie dzi­ałanie aplikacji).

Ale zaczni­jmy od początku — czyli jak dodać Spring Boot do projektu.

Dodawanie zależności

W tym miejs­cu zakładamy, że pro­jekt jest budowany z uży­ciem Mave­na. Spring Boot wspiera także Gra­dle, stosowną kon­fig­u­rację zna­jdziesz oczy­wiś­cie w doku­men­tacji.

Najprost­szym sposobem kon­fig­u­racji jest dodać sekcję <par­ent> do naszego POM’a (o ile jeszcze takiej nie ma — w tym wypad­ku zerknij do lin­ka do doku­men­tacji poniżej, gdzie jest opisane jak skon­fig­urować pro­jekt w takiej sytuacji):

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.6.RELEASE</version>
</parent>

A następ­nie do sekcji <depen­den­cies> dodać następu­jącą zależność:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Taka kon­fig­u­rac­ja wystar­czy, aby korzys­tać ze Spring Boo­ta. Jeśli w zależnoś­ci­ach masz także SpringFrame­work i mod­uły — możesz je usunąć, ponieważ są one pobier­ane w odpowied­nich wer­s­jach przez powyższą zależność.

Więcej infor­ma­cji o tym, jak skon­fig­urować pro­jekt z Maven­em (w tym jak skon­fig­urować pro­jekt nie uży­wa­jąc ‘par­ent poma’) zna­jdziesz w doku­men­tacji, w sekcji o Mave­nie.

Konfiguracja aplikacji

Pod­sta­wowa kon­fig­u­rac­ja sprowadza się do stworzenia klasy z jed­ną adno­tacją — @SpringBootApplication :

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Adno­tac­ja ta powodu­je, że uruchami­ana jest automaty­cz­na kon­fig­u­rac­ja (m.in. akty­wowana jest kon­fig­u­rac­ja MVC, jeśli dodal­iśmy do zależnoś­ci mod­uł ‑web) a także wyszuki­wane są wszys­tkie klasy z adno­tac­ja­mi Springa w danym pakiecie (i podrzęd­nych — zachowanie jest iden­ty­czne jak w przy­pad­ku adno­tacji @ComponentScan bez para­metrów opisanej wyżej).

Taka klasa zastępu­je nam kon­fig­u­rację kon­tenera (web.xml) oraz pod­sta­wową kon­fig­u­rację mod­ułów — w tym momen­cie aplikac­ja jest gotowa do uru­chomienia (zakłada­jąc oczy­wiś­cie, że wszys­tkie niezbędne do jej dzi­ała­nia ele­men­ty zostaną wykryte pod­czas skanowa­nia pakietów).

Więcej szczegółów i opcji zna­jdziesz w doku­men­tacji Spring­Boot.

Pozostałe ustawienia i funkcje

Ponieważ Spring Boot ofer­u­je znacznie więcej opcji i ciekawych możli­woś­ci, w przyszłoś­ci poświęcimy mu osob­ny wpis z bardziej szczegółowym opisem — z pewnoś­cią jest to bib­liote­ka warta uwa­gi, nawet jeśli nie planu­jesz korzys­tać ze wszys­t­kich ofer­owanych przez nią możliwości.

Podsumowanie

W tym wpisie opisal­iśmy, jak moż­na zamienić aplikację z kon­fig­u­racją XML na kon­fig­u­rację w 100% z uży­ciem Javy. Wszys­tkie opisane tech­ni­ki są dostęp­ne od Springa 3.1 — jeśli Two­ja aplikac­ja korzys­ta z nowszej wer­sji (a zde­cy­dowanie powin­na ;) ) to możesz zas­tosować opisane sposo­by. W kole­jnej częś­ci opisze­my także kon­fig­u­rację SpringSe­cu­ri­ty — prze­niesie­nie kon­fig­u­racji do Javy w tym wypad­ku jest nieco mniej oczywiste.

Czy warto?

Kiedyś najpraw­dopodob­niej zmierzysz się z prob­le­mem aplikacji, która zaw­iera tony kon­fig­u­racji XML — zami­ana jej całej wyma­gała­by znaczącego wysiłku i dużej iloś­ci cza­su. Pytanie ‘czy warto’ w tym wypad­ku należy sza­cow­ać indy­wid­u­al­nie — jeśli potrze­bu­jesz dodać tylko jed­ną funkcję czy coś popraw­ić, pory­wanie się na zmi­anę całej kon­fig­u­racji jest praw­dopodob­nie zbyt ryzykowne. Kon­fig­u­rac­ja XML i adno­tac­je mogą jed­nak współdzi­ałać bez prob­le­mu! Dlat­ego doda­jąc nową kon­fig­u­rację, sko­rzys­taj z adno­tacji. Jeśli jed­nak w aplikacji planowane są duże zmi­any, warto poświę­cić czas na przepisanie (i wery­fikację!) kon­fig­u­racji — nie tylko ułatwi to przyszłe zmi­any, ale poz­woli zespołowi lep­iej poz­nać sposób, w jaki dzi­ała system.

Pod­sumowu­jąc — w długim ter­minie warto, ale cza­sem ryzyko i koszt są zbyt duże.