Post on 04-Dec-2014
description
CDI Portable Extensions Czyli jak zręcznie manipulować beanami
Adam Warski @adamwarski
Kim jestem?
¤ Adam Warski
¤ Współzałożyciel SoftwareMill ¤ Niestandardowe Oprogramowanie w Standardzie
¤ Autor Hibernate Envers
¤ http://www.warski.org/blog
Agenda
¤ Wstęp do CDI
¤ Wstęp do Portable Extensions
¤ Demo
¤ Real-life
CDI
¤ Contexts & Dependency Injection
¤ JEE6
¤ @Inject!
¤ Wiele innych adnotacji
¤ Dużo punktów rozszerzeń
Bean
¤ Każda klasa: ¤ Z domyślnym konstruktorem
¤ Z konstruktorem z adnotacją @Inject!
¤ W archiwum (.jar) musi znajdować się beans.xml!
¤ Np.:
public class HelloWorld {!!public String sayHello() {!! !return “Hello World!”;!!}!
}!
Zasięgi (Scopes)
¤ Domyślny: dependent (brak adnotacji, ew. @Dependent)!
¤ Poza tym: ¤ @RequestScoped!¤ @ConversationScoped!¤ @SessionScoped!¤ @ApplicationScoped!
Portable Extensions
¤ API
¤ Wpływają na proces tworzenia beanów
¤ Działają z każdą implementacją CDI
¤ Seria eventów, które możemy obserwować
Portable Extensions
¤ Przetwarza wszystkie beany w aplikacji
¤ .jar musi zawierać plik
javax.enterprise.inject.spi.Extension
z nazwą rozszerzenia (Java ServiceLoader)
Demo
¤ Cały kod dostępny na GitHubie! ¤ https://github.com/adamw/portable-extensions-demo
Real-life
¤ Rozszerzenia dostępne na ¤ https://github.com/softwaremill/softwaremill-common
¤ Open-source
¤ Wykorzystywane przez nas produkcyjnie
¤ Wystarczy dodać zależność w pomie
Stackable Security Interceptors
¤ Dodaje security interceptor sprawdzający „sumę” warunków określonych na metodzie/klasie
Real-life #1
@MustBeLoggedIn!public class ProductManager {!
!public Product read (int id) { … }!!
!@MustBeAdministrator!!public void deleteAll() { … }!
}!
Stackable Security Interceptors
¤ Meta-adnotacja definiuje warunek logiczny, który powinien być sprawdzony
Real-life #1
@Target({TYPE, METHOD })!@Retention(RUNTIME)!@SecureBinding!@Secure(“#{user.administrator == true}”)!public @interface MustBeAdministrator {}!
Auto-factories
¤ Dynamiczne tworzenie beanów
¤ Analogiczne do assisted inject w Guice
Real-life #2
public interface PriceCalculator {! int getFinalPrice(); !! interface Factory {! PriceCalculator create(Product product);! }!}!
Auto-factories
Real-life #2
public interface PriceCalculator {! int getFinalPrice(); !! interface Factory {! PriceCalculator create(Product product);! }!}!
@CreatedWith(PriceCalculator.Factory.class)!public class PriceCalculatorImpl implements PriceCalculator {! @Inject! public PriceCalculatorImpl(!
!@FactoryParameter Product product,!!Discounts discounts) { … }!
! …!}!
Auto-factories
¤ Możemy wstrzyknąć fabrykę bez konieczności jej pisania!
Real-life #2
public class User {! @Inject! PriceCalculator.Factory priceCalculatorFactory;!! void buy(Product product) {! int price = priceCalculatorFactory!
! !.create(product)!! !.getFinalPrice();!
// …! }!}!
AOP++
¤ AOP pozwala dodać interceptor na podstawie sygnatury
¤ Z Portable Extensions: dodatkowe możliwości
¤ „Dynamiczny AOP” ¤ na podstawie pliku konfiguracyjnego
¤ dowolna logika (w Javie, nie XMLu!)
¤ np. dodanie timing interceptora do konkretnych beanów
Real-life #3
Linki
¤ https://github.com/adamw/portable-extensions-demo
¤ https://github.com/softwaremill/softwaremill-common
¤ http://www.jboss.org/arquillian
¤ http://seamframework.org/Weld
Dziękuje! Pytania?
¤ adam@warski.org
¤ @adamwarski