1.
CDI Portable Extensions
Czyli jak zręcznie manipulować beanami
Adam Warski @adamwarski
2.
Kim jestem?
¤ Adam Warski
¤ Współzałożyciel SoftwareMill
¤ Niestandardowe Oprogramowanie w Standardzie
¤ Autor Hibernate Envers
¤ http://www.warski.org/blog
3.
Agenda
¤ Wstęp do CDI
¤ Wstęp do Portable Extensions
¤ Demo
¤ Real-life
4.
CDI
¤ Contexts & Dependency Injection
¤ JEE6
¤ @Inject!
¤ Wiele innych adnotacji
¤ Dużo punktów rozszerzeń
5.
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!”;!
!}!
}!
7.
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ć
8.
Portable Extensions
¤ Przetwarza wszystkie beany w aplikacji
¤ .jar musi zawierać plik
javax.enterprise.inject.spi.Extension
z nazwą rozszerzenia (Java ServiceLoader)
9.
Demo
¤ Cały kod dostępny na GitHubie!
¤ https://github.com/adamw/portable-extensions-demo
10.
Real-life
¤ Rozszerzenia dostępne na
¤ https://github.com/softwaremill/softwaremill-common
¤ Open-source
¤ Wykorzystywane przez nas produkcyjnie
¤ Wystarczy dodać zależność w pomie
11.
Real-life #1
Stackable Security Interceptors
¤ Dodaje security interceptor sprawdzający „sumę” warunków
określonych na metodzie/klasie
@MustBeLoggedIn!
public class ProductManager {!
!public Product read (int id) { … }!
!
!@MustBeAdministrator!
!public void deleteAll() { … }!
}!
12.
Real-life #1
Stackable Security Interceptors
¤ Meta-adnotacja definiuje warunek logiczny, który powinien
być sprawdzony
@Target({TYPE, METHOD })!
@Retention(RUNTIME)!
@SecureBinding!
@Secure(“#{user.administrator == true}”)!
public @interface MustBeAdministrator {}!
13.
Real-life #2
Auto-factories
¤ Dynamiczne tworzenie beanów
¤ Analogiczne do assisted inject w Guice
public interface PriceCalculator {!
int getFinalPrice(); !
!
interface Factory {!
PriceCalculator create(Product product);!
}!
}!
14.
Real-life #2
Auto-factories
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) { … }!
!
…!
}!
15.
Real-life #2
Auto-factories
¤ Możemy wstrzyknąć fabrykę bez konieczności jej pisania!
public class User {!
@Inject!
PriceCalculator.Factory priceCalculatorFactory;!
!
void buy(Product product) {!
int price = priceCalculatorFactory!
! !.create(product)!
! !.getFinalPrice();!
// …!
}!
}!
16.
Real-life #3
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
17.
Linki
¤ https://github.com/adamw/portable-extensions-demo
¤ https://github.com/softwaremill/softwaremill-common
¤ http://www.jboss.org/arquillian
¤ http://seamframework.org/Weld