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
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() { … }!
            }!
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 {}!
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);!
            }!
        }!
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) { … }!
!
    …!
}!
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();!
          // …!
      }!
  }!
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
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

CDI Portable Extensions

  • 1.
    CDI Portable Extensions Czylijak zręcznie manipulować beanami Adam Warski @adamwarski
  • 2.
    Kim jestem? ¤  AdamWarski ¤  Współzałożyciel SoftwareMill ¤  Niestandardowe Oprogramowanie w Standardzie ¤  Autor Hibernate Envers ¤  http://www.warski.org/blog
  • 3.
    Agenda ¤  Wstęp doCDI ¤  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!”;! !}! }!
  • 6.
    Zasięgi (Scopes) ¤  Domyślny:dependent (brak adnotacji, ew. @Dependent)! ¤  Poza tym: ¤  @RequestScoped! ¤  @ConversationScoped! ¤  @SessionScoped! ¤  @ApplicationScoped!
  • 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ć
  • 9.
    Portable Extensions ¤  Przetwarzawszystkie beany w aplikacji ¤  .jar musi zawierać plik javax.enterprise.inject.spi.Extension z nazwą rozszerzenia (Java ServiceLoader)
  • 10.
    Demo ¤  Cały koddostępny na GitHubie! ¤  https://github.com/adamw/portable-extensions-demo
  • 11.
    Real-life ¤  Rozszerzenia dostępnena ¤  https://github.com/softwaremill/softwaremill-common ¤  Open-source ¤  Wykorzystywane przez nas produkcyjnie ¤  Wystarczy dodać zależność w pomie
  • 12.
    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() { … }! }!
  • 13.
    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 {}!
  • 14.
    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);! }! }!
  • 15.
    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) { … }! ! …! }!
  • 16.
    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();! // …! }! }!
  • 17.
    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
  • 18.
  • 19.