Tworzenie samodzielnej aplikacji ze Spring Framework w NetBeans IDE 6.9

Z Jacek Laskowski - Wiki Projektanta Java EE

Artykuł przedstawia kroki niezbędne do stworzenia samodzielnej aplikacji korzystającej ze Spring Framework w zintegrowanym środowisku programistycznym NetBeans IDE 6.9.

Wymagane oprogramowanie to jedynie wspomniany NetBeans IDE 6.9.

Kompletny projekt jest dostępny jako SpringApplication.zip.

Spis treści

Stworzenie projektu SpringApplication

Rozpoczynamy od stworzenia samodzielnej aplikacji SpringApplication. Wciskamy kombinację klawiszy Cmd+Shift+n (File > New Project) i wybieramy Java Application w kategorii Java.

Plik:springnetbeans69-javaapplication.png

Wciskamy przycisk Next.

Podajemy dane aplikacji i wciskamy Finish.

Plik:springnetbeans69-newjavaapplication.png

Po chwili, w widoku Projects po lewej, pojawi się struktura projektu SpringApplication oraz po prawej edytor z klasą główna Main.

Plik:springnetbeans69-projektutworzony.png

Dodanie biblioteki Spring Framework 3.0.2.RELEASE

W widoku Projects z menu kontekstowego w gałęzi Libraries wybieramy Add Library.

Plik:springnetbeans69-addlibrary.png

Wybieramy bibliotekę Spring Framework 3.0.2.RELEASE.

Plik:springnetbeans69-springframework-library.png

Wciskamy przycisk Add Library.

Uruchomienie Springa przez ClassPathXmlApplicationContext

Z tak przygotowanym projektem jesteśmy gotowi do programowania korzystając z funkcjonalności oferowanej przez Spring Framework. Na początek wystarczy samo zainicjowanie Springa na bazie konfiguracji zapisanej w beans.xml przez org.springframework.context.support.ClassPathXmlApplicationContext.

package springapplication;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
/**
 * @author Jacek Laskowski
 */
public class Main {
 
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    }
}

Sprawdzamy poprawność aplikacji uruchamiając ją klawiszem F6.

run:
Jul 5, 2010 9:40:52 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@29173ef: startup date [Mon Jul 05 21:40:52 CEST 2010]; root of context hierarchy
Jul 5, 2010 9:40:53 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans.xml]
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [beans.xml];
nested exception is java.io.FileNotFoundException: class path resource [beans.xml] cannot be opened because it does not exist
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:341)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)
        at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:126)
        at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:92)
        at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
        at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:465)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:395)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
        at springapplication.Main.main(Main.java:11)
Caused by: java.io.FileNotFoundException: class path resource [beans.xml] cannot be opened because it does not exist
        at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:141)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:328)
        ... 13 more
Java Result: 1
BUILD SUCCESSFUL (total time: 3 seconds)

Uruchomienie aplikacji zakończy się błędem niedostępności pliku konfiguracyjnego Springa - Caused by: java.io.FileNotFoundException: class path resource [beans.xml] cannot be opened because it does not exist. Oczekiwane.

Utworzenie pliku konfiguracyjnego Springa - beans.xml

Z menu kontekstowego projektu wybierając menu New > Other... lub wciskając kombinację klawiszy Cmd+n wybieramy menu Other > Spring XML Configuration File.

Plik:springnetbeans69-springxmlconfigurationfile.png

Wciskamy przycisk Next >.

W oknie dialogowym New Spring XML Configuration File definiujemy:

  • File Name: beans (rozszerzenie .xml jest dodawane automatycznie)

oraz upewniamy się, że Folder wskazuje na katalog src.

Plik:springnetbeans69-beansxml.png

Wciskamy przycisk Next, a później Finish.

Struktura projektu powinna przedstawiać się jak poniżej.

Plik:springnetbeans69-strukturaprojektowazbeansxml.png

Ponownie uruchamiamy aplikację wciskając klawisz F6.

run:
Jul 5, 2010 9:52:05 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2c091cee: startup date [Mon Jul 05 21:52:05 CEST 2010]; root of context hierarchy
Jul 5, 2010 9:52:05 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans.xml]
Jul 5, 2010 9:52:07 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2f93c0cf: defining beans []; root of factory hierarchy
BUILD SUCCESSFUL (total time: 3 seconds)

Tym razem aplikacja została uruchomiona poprawnie, co sprowadziło się do zainicjowania pustego kontekstu Springa bez jakiegokolwiek ziarna springowego. Stwórzmy jedno.

Stworzenie ziarna springowego - ziarno

Ziarno springowe jest zwykle niczym innym jak klasą javową, która nie jest zobowiązana do implementacji interfejsu czy rozszerzania klasy pochodzącej ze Springa. Ten rodzaj klasy nazywamy POJO (ang. Plain Old Java Object), co podkreśla "czystość techniczną" tak skonstruowanej klasy.

Ziarno springowe składa się z dwóch elementów - klasy (czasami, a może nawet zwykle, również interfejsu) oraz jej definicji w pliku konfiguracyjnym Springa.

Zacznijmy od stworzenia klasy pakiet.ZiarnoSpringowe. Cmd+n i wybieramy Java > Java Class.

Plik:springnetbeans69-javaclass.png

Wciskamy Next, aby w kolejnym kroku zdefiniować klasę - jej nazwę i pakiet.

Plik:springnetbeans69-newjavaclass.png

Wciskamy przycisk Finish.

Definiujemy metodę public void wypiszNaEkran(String komunikat):

package pakiet;
 
/**
 * @author Jacek Laskowski
 */
public class ZiarnoSpringowe {
 
    public void wypiszNaEkran(String komunikat) {
        System.out.println("Komunikat: " + komunikat);
    }
}

Podczas implementacji warto skorzystać z udogodnień NetBeans IDE takich jak Ctrl+spacja czy szablonu sout.

Deklaracja ziarna springowego w pliku konfiguracyjnym Springa - beans.xml

Kolejnym krokiem jest zadeklarowanie klasy jako ziarna springowego w naszym pliku konfiguracyjnym Springa - beans.xml. Można również skorzystać z adnotacji, ale tym razem będziemy deklarować wyłącznie przez konfigurację w pliku XML. Do pliku beans.xml dodajemy pojedynczą linię - element bean.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 
    <bean id="ziarno" class="pakiet.ZiarnoSpringowe" />
 
</beans>

Kolejne uruchomienie (przycisk F6). Tym razem powinniśmy zauważyć, że Spring rozpoznał i zainicjował instancję ziarna o nazwie ziarno na bazie klasy pakiet.ZiarnoSpringowe jak zdefiniowano w pliku beans.xml.

run:
Jul 5, 2010 10:07:55 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@a4a63d8: startup date [Mon Jul 05 22:07:55 CEST 2010]; root of context hierarchy
Jul 5, 2010 10:07:55 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans.xml]
Jul 5, 2010 10:07:55 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5117f31e: defining beans [ziarno]; root of factory hierarchy
BUILD SUCCESSFUL (total time: 1 second)

Użycie ziarna springowego w aplikacji

Pozostaje skorzystać z tego ziarna w naszej aplikacji, w klasie Main. Dodajemy do niej wywołanie metody public <T> T getBean(String name, Class<T> requiredType)

package springapplication;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pakiet.ZiarnoSpringowe;
 
/**
 * @author Jacek Laskowski
 */
public class Main {
 
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        ZiarnoSpringowe ziarnoSpringowe = context.getBean("ziarno", ZiarnoSpringowe.class);
    }
}

Ponownie F6 i...

run:
Jul 5, 2010 10:13:27 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@19e0ff2f: startup date [Mon Jul 05 22:13:27 CEST 2010]; root of context hierarchy
Jul 5, 2010 10:13:27 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans.xml]
Jul 5, 2010 10:13:27 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6a5f6303: defining beans [ziarno]; root of factory hierarchy
BUILD SUCCESSFUL (total time: 1 second)

...całość zestawiona poprawnie. Możemy dalej poznawać Springa z pomocą NetBeans IDE 6.9.

Na zakończenie wywołajmy metodę wypiszNaEkran na zwróconym obiekcie.

package springapplication;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pakiet.ZiarnoSpringowe;
 
/**
 * @author Jacek Laskowski
 */
public class Main {
 
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        ZiarnoSpringowe ziarnoSpringowe = context.getBean("ziarno", ZiarnoSpringowe.class);
        ziarnoSpringowe.wypiszNaEkran("Działa!");
    }
}

Na konsoli powinno pojawić się magiczne Komunikat: Działa!.

run:
Jul 5, 2010 10:16:42 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@19e0ff2f: startup date [Mon Jul 05 22:16:42 CEST 2010]; root of context hierarchy
Jul 5, 2010 10:16:42 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans.xml]
Jul 5, 2010 10:16:42 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5117f31e: defining beans [ziarno]; root of factory hierarchy
Komunikat: Działa!
BUILD SUCCESSFUL (total time: 2 seconds)

Faktycznie działa!

Osobiste