czwartek, 5 czerwca 2014

Introduce to Spring Framework - basic knowlegde..

Po raz pierwszy spotkałem się ze Springiem w 2005 roku. Wtedy używałem wersji 1.2. Na samym początku nie czułem bardzo zalet jakie oferował on programiście. Po prostu wiedziałem, że można definiować beany i ich zachowanie w xml'ach, dzięki czemu jakiś kontener w przypadku wyraźnej potrzeby odpowiednio wstrzeli daną implementację bazując na interfejsie. Dla mnie to był fajny koncept ale nic poza tym. Czułem jedynie zaletę wynikającą z loose coupling, wspomaganie dla high cohesion i ogólnego testability. Tyle.....
Z biegiem czasu poznałem Spring MVC i od razu poczułem, żę Struts musi odejść do lamusa. Potem doceniłem warstwę abstrakcji dla DAO, wsparcie dla Hibernate, Spring templates itd.

 Spring to :
  - programowanie na interfejsach
  - proxy
  - aop
  - templates (RestTemplate,JmsTemplate,JDBCTemplate etc)
  - udostępnienie przejrzystego API
  - wzorzec DI
  - lekkie podejście do architektury oparte na zwykłym POJO

Pozwala :
 - uprościć proces wytwarzania oprogramowania
 - zwiększyć testowalność
 - izolacja API od złożonego kodu
 -  programowanie deklaratywne
 - modularność




Obsługa : 

- AOP -> Spring AOP, AspectJ
  (hermetyzacja zadań, problemy przekrojowe)
  przykład wykorzystania to :
        - logowanie,
        - cache,
        - transactions,
        - security
        - etc

Zalety :
  - zwiększenie modularności
  - zwiększenie możliwości tworzenie elementów wielokrotnego użytku czyli nie powielamy kodu
  - brak zaśmiecania kodu biznesowego kodem technicznym

Wady :
  - zwiększenie złożoności programu
  - kod może być nie do końca przejrzysty i zrozumiały
  - trudniej debugować kod oparty na dynamicznych proxy


- dostęp do danych oraz integracja
   - upraszcza dostęp do danych (eliminacja boilerplate code)
     (JDBC template operuje już na wyrażeniach lamba od Spring 4)
    - standaryzuje obsługę wyjątków
   - obsługuje fabryki sesji
    -  pule połączeń
    - wspiera ORM
    - OXM (Castor, JAXB, JiBX, XmlBeans, XStream)
    - JMS

- MVC
  - otwarta furtka dla Struts, JSF, Velocity, FreeMarker czy wreście mój ulubiony ThymeLeaf
 
TIP : Zawsze rozważ użycie ThymeLeaf  aby Twój development części frontend był sprawniejszy niż dotąd. Możliwość projektowania oraz implementowania widoków w całkowitej separacji od projektu. W JSP było niemożliwe z uwagi na tagi.

TIP : JSP jest już deprecated od wersji J2EE 6 więc.....

- Testowanie 
 - wsparcie dla JUnit, TestNg czy Mockito.

Tip : Testowanie nigdy nie było łatwiejsze. Spring wymusza większą modularność , oraz dostarcza IoC dzięki temu można przetestować dosłownie każdy kawałek kodu

Jak działa Spring ?  To proste  (rys poniżej):
    - POJO + konfiguracja
    - kontener DI (luźne wiązania między komponentami)

















Ważne jest to, iż kod pisany w Springu nie uzależnia nas od jego API.
Co to znaczy ? - To, że taki kod możemy użyć w innym rozwiązaniu czy zrębie programowym. Co najwyżej musimy czasem zastosować jaką adnotację ale to tyle. Konfiguracja i zachowanie beanów są doskonale odseparowane od kodu biznesowego aplikacji. To wielka zaleta.


Mamy możliwość zdefiniować kontekst na kilka sposobów :
 - używając XML
 - używając adnotacji (Spring 2.5)
 - używając javaConfig (java-based configuration) (Spring 3.0)
 - stosując podejście hybrydowe

Podejście oparte na XML:


Charakterystyka : 
    - <beans/>
    - namespaces
    - ClassPathXmlApplicationContext({context.xml}) - > rejestracja usługi

Dobre praktyki :
  - w nazwach namespaces nie używaj wersji. Uniezależnisz się w ten sposób od danej wersji.
  - rozdzielaj pliki konfiguracyjne w przemyślany sposób np funkcjonalność aop umieść w aop.xml,
    funkcjonalność cache w cache.xml , dostęp do danych w spring-data.xml  itd

Tip :  ścieżka do pliku z konfiguracją może znajdować się z odrębnej lokalizacji plikowej : 'file:/etc/config/personalBlog/services.xml' lub po prostu należeć do classpath projektu 'classpath:repository.xml'

- zawsze starać posiłkować się odpowiednim namespaces
- zawsze gdzie tylko to możliwe staraj się parametryzować kontekst poprzez placeholders -> ${}
- wszystkie konfiguracje staraj się trzymać w plikach properties czy yaml  tak aby nie zachodziła potrzeba modyfikacji xml'a

TIP : yaml - > bardziej oszczędny format dla properties

Zalety :
   - dobra czytelność
   - kod nie jest zależny od Springa / konfiguracja w oddzielnych plikach xml
   - pozwala na separację logiczną (SoC).

Wady:
  - verbosity
  - namespace zamknięty na rozszerzenia
  - trudno stworzyć swój własny namespace
  - not type-safe (brak bezpieczeństwa typu)

Użycie : 
 
 
Podejście oparte na Spring JavaConfig
   Charakterystyka : 
       - @Configuration - </>
       - @Bean    -> <bean/>
       - @Import -> <import/>
       AnnotationConfigApplicationContext - > rejestracja usługi
       - @AnnotationDrivenConfig -> enable the @Autowired
       - @ImportXml("classpath:cache.xml") - > import config based on xml
       - @ComponentScan -> <context-component-scan/> 
       - @EnableJpaRepositories -> <jpa:repositories base-package='{}'/>
       - @EnableWecMvc -> <mvc:annotation-driven/>
       - @EnableTransactionManagement -> <tx:annotation-driven/>
       - @PropertySource ->  <context:property-placeholder location='{}'/> 
       - @EnableAspectJAutoProxy -> <aop:aspectj-autoproxy/>
       - @EnableLoadTimeWeaving -> <context:load-time-weaver/>
       - @EnableMBeanExport -> <context:mbean-export/>
       - @EnableAsync -> <task:annotation-driven/>
       - @EnableCaching -> <cache:annotation-driven/> 

Przykład :  

Zalety : 
  - pełna programowa kontrola
  - wsparcie dla OO
  - integracja z innymi stylami wstrzeliwania zależności 
  - od Spring 3.0 wbudowana w core
  - bardziej odporna na błędy (już w czasie kompilacji) 
  - wsparcie refaktoringu ze strony IDE 
  - autocomplete IDE feature

Wady : 
   - czasem bardziej verbosity niż podejście XML
   - może wydawać się trudniejsza do zrozumienia niż standard XML
   - uzależnia kod od Springa

Podejście oparte na @Annotation

  Charakterystyka : 
      - @Component / @Repository / @Service / @Controller etc
      - @Autowired / @Inject / @Resource etc
       @Repository - > added  PersistenceExceptionTranslator functionality
      - @Value("${nazwa_property}") - wstrzyknięcie property

    
Zalety : 
  - łatwo można tworzyć swoje zachowania
  - eliminacja XML'a
  - łatwo zrozumieć kod i jego działanie

Wady : 
  - uzależnienie kod od Springa

Spring              ->            java.inject.*
@Autowired     ->            @Inject
@Component   ->            @Named
@Scope            ->            @Scope -> @Singleton
@Qualifier        ->            @Qualifier , @Named
        


WebApplicationIntializer - > eliminuje potrzebę użycia web.xml w specyfikacji Servlet API 3.0 w górę.




Powoływanie do życia beanu możemy uzyskać  przez :
 - wywołanie jego konstruktora
 - zastosowanie static method factory (Zastąp konstruktory statycznymi metodami factory)

 - zastosowanie factory method

Dependency injection osiągniemy głównie przez :
  - użycie settera
  - użycie konstruktora  

Tip : Użycie constructor injection zapobiega występowaniu cyklicznych zależności.

Tip : c-namespace dla konstruktora

Tip : Jeśli jakaś zależność jest obligatoryjna podczas tworzenia bean'a zastosuj wstrzyknięcie przez konstruktor, dzięki czemu będziesz miał pewność co do kolejności inicjalizacji grafu beanów oraz pokażesz swoje intencje w kodzie.

Tip : użyj @Required przy setterze jeśli zależność jest obligatoryjna do zbudowania zależności

Tip :  jeśli zależność nie jest obligatoryjna możesz użyć @Autowired(required=false)


Dla wczesnej inicjalizacji komponentu lub czyszczenia zasobów użyj :
  - destroy-method="{close}" 
  - init-method="{init}"

Init & Destroy
w przypadku xml  skorzystać z namespaces i opisać lepiej zachowanie beana:

  init-method="openResource" destroy-method="closeResource"

lub wykorzystując anotacje  @PostConstruct i @PreDestroy

lub  wykorzystując interfejsy

   - InitializingBean
   - DisposableBean

Referencje : 
  - do innego beana : <ref bean="someBean"/>
  - @Autowired Bean bean


Cykl życia bean : 
1.BeanNameAware
2.BeanClassLoaderAware
3.BeanFactoryAware
4.ResourceLoaderAware
5.ApplicationEventPublisherAware
6.MessageSourceAware
7. AplicationContextAware
8.ServletContextAware (web)
9.PostProcessBeforeIntialization
10.InitializationBean
11.PostProcessAfterInitialization



źródło  : khoaphamtechnology.wordpress.com



@Lazy - odracza inicjalizacje bean'a do możliwe jak najbardziej kiedy faktycznie jest od niezbędny

@DependsOn - mówi kontenerowi springa po prostu: "czekaj ten bean wymaga do działania innego beana więc zbuduj bean zależnego na samym początku"

@Primary - daje pierwszeństwo dla bean oznaczonego tą annotacją podczas procesu wstrzeliwania zależności


@Lazy, @DependsOn i @Primary mają swój odpowiednik w XML.


ApplicationEventPublisherAware - rejestrowanie eventów Springowych

Event-based communication between beans = observator pattern in Spring
  - bean dziedziczy po ApplicationEvent
  - publikator wiadomości implementuje  ApplicationEventPublisherAware
  - zainteresowany zdarzeniem implementuje generyczny ApplicationListener


Spring Profile : (czyli tworzenie zachować w zależności od .... * lepsza wersja to @Conditional dostępny w Spring 4. - > podstawa działania Spring Boot)

Sposób programowy:

Sposób JVM :

     -Dspring.profiles.activate=first

Sposób deklaratywny z web.xml:

Sposób z testów :

Spring profile

Brak komentarzy:

Prześlij komentarz