Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Contexts and Dependency Injection for the JavaEE platform


Published on

Contexts and Dependency Injection for the JavaEE platform

  1. 1. CDI – Contexts andCDI – Contexts and Dependency Injection for theDependency Injection for the JavaEE platform (JSR299)JavaEE platform (JSR299) Bozhidar Bozhanov Bulgarian Association of Software Developers
  2. 2. About meAbout me • Senior Java Developer at Fish4 • 3+ years experience with Spring and dependency injection • Implementor of JSR-299 as a university project • Committer at Hector (Java Cassandra API) •
  3. 3. Dependency injection?Dependency injection? • Classes define what are their dependencies, not how they obtain them • Object dependencies are set externally • Unit-test and mocking friendly • DI frameworks - objects are managed and have a lifecycle
  4. 4. HistoryHistory • Theoretical basis - GoF Hollywood principle; Steffano Mazzocchi • Spring – 2002/2003, Rod Johnson • Pico Container - 2003 • Martin Fowler popularized the term - 2004 • JBoss Seam, Google Guice, EJB 3.0 • Contexts and Dependency Injection (JSR- 299, JavaEE 6) - 2006-2009
  5. 5. Current problemsCurrent problems • Problematic integration between JavaEE components • „Crippled“ dependency-injection in EJB • No standard – only propriatary DI frameworks (spring, guice, seam) • Extended reliance on string qualifiers (no compile-time safety)
  6. 6. JSR-299JSR-299 • What's a JSR? • CDI Initially named „Web Beans“ • Expert Group formed in June 2006, spec-lead is Gavin King • Early draft (2007), Public review (2008), Final draft (mid-2009), Ralease (Dec 2009) • Bob Lee (Guice) left the expert group • IBM voted „No“, Google voted „Yes“, VMware (SpringSource) and Eclipse didn't vote.
  7. 7. What is CDIWhat is CDI • Type-safe DI framework (based on Seam, Guice and Spring) • Uses JSR-330 (Dependency Injection for Java), lead by Rod Johnson (Spring) and Bob Lee (Guice), which defines only DI annotations (for JavaSE) • DI JavaEE-wide – JSF managed beans, EJB, JavaEE Resources
  8. 8. Implementations; web profileImplementations; web profile • Three implementations: JBoss Weld, Apache OpenWebBeans and Resin CanDI • Only one stable at the moment – Weld, used in Glassfish v3 and JBoss AS (5.2, 6) • JavaEE 6 has the so-called „profiles“. CDI is part of the „Web profile“ • CDI implementations are not limited to application servers (with the help of extensions)
  9. 9. Java EE structure with CDIJava EE structure with CDI
  10. 10. Beans and bean archivesBeans and bean archives • A bean archive has META-INF/beans.xml • All classes within a bean archive are beans, and eligible for injection • All classes in outside bean archives are not beans • Beans can have type(s), scope, EL name, qualifiers, interceptors. • Beans can be JSF beans, EJBs, JavaEE resources
  11. 11. • @javax.inject.Inject is used:@javax.inject.Inject is used: InjectionInjection publicpublic classclass OrdersBean {OrdersBean { @Inject@Inject privateprivate OrdersDaoOrdersDao daodao;; }} • The „dao“ field is called „injection point“.The „dao“ field is called „injection point“. Injection point types are:Injection point types are: • FieldField • ConstructorConstructor • SetterSetter • InitializerInitializer
  12. 12. Injection pointsInjection points publicpublic classclass OrdersBean {OrdersBean { @Inject@Inject privateprivate OrdersDaoOrdersDao daodao;; @Inject@Inject publicpublic OrdersBean(OrdersDao dao){}OrdersBean(OrdersDao dao){} @Inject@Inject publicpublic voidvoid init(OrdersDao dao) {}init(OrdersDao dao) {} @Inject@Inject publicpublic voidvoid setOrdersDao(OrdersDao dao){}setOrdersDao(OrdersDao dao){} }}
  13. 13. • Inject into:Inject into: – POJOsPOJOs – EJB Session BeansEJB Session Beans – ServletsServlets • Injection candidates:Injection candidates: – POJOsPOJOs – EJB Session BeansEJB Session Beans – JavaEE ResourcesJavaEE Resources Injection targetsInjection targets
  14. 14. Bean scopesBean scopes • Built-in scopes (normal vs pseudo): • @ApplicationScoped – i.e. Singleton • @RequestScoped – created on http request • @SessionScoped – within a HttpSession • @ConversationScoped – between request and session • @Dependent (default, pseudo) – the object lives as long as the object it is injected into • Custom scopes
  15. 15. • @Named(@Named(""beanNamebeanName"")). Defaults to the. Defaults to the decapitalized, simple name of the classdecapitalized, simple name of the class • Used in EL expressions:Used in EL expressions: Bean nameBean name <<h:outputTexth:outputText valuevalue=="#{orderBean.order.price}""#{orderBean.order.price}" />/> • Used in injections (discouraged)Used in injections (discouraged) @Inject@Inject @Named@Named(("ordersBean""ordersBean")) privateprivate OrdersBeanOrdersBean orderBeanorderBean;;
  16. 16. • Qualifiers are annotations (unlike in spring):Qualifiers are annotations (unlike in spring): QualifiersQualifiers @Qualifier //retention & target ommitted@Qualifier //retention & target ommitted publicpublic @interface@interface SynchronousSynchronous {}{} • Qualifiers are used to differentiate beans with the sameQualifiers are used to differentiate beans with the same type:type: @@InjectInject @@SynchronousSynchronous privateprivate CreditCardProcessor processor;CreditCardProcessor processor; @@SynchronousSynchronous publicpublic classclass SynchronousCreditCardProcessorSynchronousCreditCardProcessor implementsimplements CreditCardProcessor {..}CreditCardProcessor {..} @@AsynchronousAsynchronous publicpublic classclass AsyncCreditCardProcessorAsyncCreditCardProcessor implementsimplements CreditCardPRocessor {..}CreditCardPRocessor {..}
  17. 17. • @Any@Any – all beans have this, unless they have– all beans have this, unless they have @New@New • @Default, @Named@Default, @Named • @New@New –– forces the container to return a new beanforces the container to return a new bean instance each timeinstance each time Built-in qualifiersBuilt-in qualifiers @@NewNew publicpublic classclass SomeBean {..}SomeBean {..} publicpublic classclass AnotherBean {AnotherBean { @@Inject SomeBean bean1;Inject SomeBean bean1; @@Inject SomeBean bean2;Inject SomeBean bean2; @@PostConstructPostConstruct voidvoid init() {init() { // false// false System.out.println(bean1 == bean2);System.out.println(bean1 == bean2); }} }}
  18. 18. • Stereotypes are used to reduce the amountStereotypes are used to reduce the amount of boilerplate code:of boilerplate code: StereotypesStereotypes @@StereotypeStereotype //denoting a stereotype//denoting a stereotype @@NamedNamed // built-in qualifier// built-in qualifier @@RequestScopedRequestScoped // scope// scope publicpublic @interface@interface RequestScopedSecureBean {}RequestScopedSecureBean {} @@RequestScopedNamedRequestScopedNamed BeanBean publicpublic classclass OrdersBean {..}OrdersBean {..}
  19. 19. DemoDemo (Beans, Injection, Qualifiers, Stereotypes, EL)
  20. 20. • A way to utilize complex constructionA way to utilize complex construction • Allow non-beans to be injected (i.e. 3Allow non-beans to be injected (i.e. 3rdrd partyparty classes outside a bean-archive)classes outside a bean-archive) • Handles object disposalHandles object disposal ProducersProducers //this class is within a bean archive//this class is within a bean archive classclass ConnectionProducer {ConnectionProducer { @Produces@Produces Connection createConnection() {Connection createConnection() { // create and return jdbc connection// create and return jdbc connection }} // when the object gets out of scope// when the object gets out of scope voidvoid dispose(dispose(@Disposes@Disposes Connection con) {Connection con) { con.close();con.close(); }} }}
  21. 21. • Allow injecting JavaEE resources:Allow injecting JavaEE resources: Producer fieldsProducer fields @@ProducesProduces @@SomeTopicSomeTopic @@Resource(name=Resource(name="topics/SomeTopic""topics/SomeTopic")) privateprivate Topic someTopic;Topic someTopic; @@ProducesProduces @@PersistenceContextPersistenceContext privateprivate EntityManager entityManager;EntityManager entityManager; @@ProducesProduces // non-JaveEE producer field// non-JaveEE producer field privateprivate Some3rdPartyBean bean =Some3rdPartyBean bean = newnew Some3rdPartyBean();Some3rdPartyBean();
  22. 22. • Gives information about the injection pointGives information about the injection point Injection point metadataInjection point metadata @@Produces Logger createLogger(InjectionPointProduces Logger createLogger(InjectionPoint injectionPoint) {injectionPoint) { returnreturn Logger.getLogger(injectionPointLogger.getLogger(injectionPoint .getMember().getDeclaringClass());.getMember().getDeclaringClass()); }} @Produces@Produces @@HttpParam(HttpParam("""")) String getParamValue(ServletRequest request,String getParamValue(ServletRequest request, InjectionPoint ip) {InjectionPoint ip) { returnreturn request.getParameter(iprequest.getParameter(ip .getAnnotation(HttpParam..getAnnotation(HttpParam.class)class).value());.value()); }} }}
  23. 23. • Decorators decorate all interfaces theyDecorators decorate all interfaces they implementimplement • @Delegate@Delegate is used to inject the originalis used to inject the original objectobject • Decorators must be explicitly listed inDecorators must be explicitly listed in beans.xml, in their respective orderbeans.xml, in their respective order • Decorators can be abstractDecorators can be abstract DecoratorsDecorators @@DecoratorDecorator publicpublic classclass LogDecoratorLogDecorator implementsimplements Logger {Logger { @@DelegateDelegate @@AnyAny privateprivate LoggerLogger loggerlogger;; @Override@Override publicpublic voidvoid log(String msg) {log(String msg) { loggerlogger.log(timestamp() +.log(timestamp() + ":"":" + msg);+ msg); }} }}
  24. 24. • Interceptor bindings (can be nested or includedInterceptor bindings (can be nested or included in stereotypes)in stereotypes) InterceptorsInterceptors @@InterceptorBindingInterceptorBinding // + retention & target// + retention & target publicpublic @interface@interface TransactionalTransactional{}{} @@InterceptorBindings @TransactionalInterceptorBindings @Transactional publicpublic @interface@interface DataAccessDataAccess {}{} • Declaring the actual interceptor:Declaring the actual interceptor: @@TransactionalTransactional @@InterceptorInterceptor publicpublic classclass TransactionInterceptor {TransactionInterceptor { @@AroundInvokeAroundInvoke publicpublic Object manage(InvocationContext ctx)Object manage(InvocationContext ctx) throwsthrows Exception { .. }Exception { .. } }}
  25. 25. • Declaring the interceptor on the target beanDeclaring the interceptor on the target bean Interceptors (2)Interceptors (2) @@TransactionalTransactional //all methods are transactional//all methods are transactional public classpublic class OrderService { .. }OrderService { .. } • Like decorators, must be enabled in beans.xmlLike decorators, must be enabled in beans.xml • Interceptors-to-intercepted targets: many-to-Interceptors-to-intercepted targets: many-to- manymany • Interceptors-to-interceptor bindings: many-to-Interceptors-to-interceptor bindings: many-to- manymany • Binding vsBinding vs @NonBinding@NonBinding interceptor attributesinterceptor attributes
  26. 26. DemoDemo (Producers, Decorators, Interceptors)
  27. 27. Programmatic lookupProgrammatic lookup @@InjectInject @@AnyAny privateprivate Instance<CreditCardProcessor> ccProc;Instance<CreditCardProcessor> ccProc; public voidpublic void processPayment(processPayment( Payment payment,Payment payment, booleanboolean synchronously) {synchronously) { Annotation qualifier = synchronouslyAnnotation qualifier = synchronously ?? newnew SynchronousLiteral()SynchronousLiteral() :: newnew AsynchronousLiteral();AsynchronousLiteral(); CreditCardProcessor actualProcessor =CreditCardProcessor actualProcessor =;; actualProcessor.process(payment);actualProcessor.process(payment); }} classclass SynchronousLiteralSynchronousLiteral extendsextends AnnotationLiteral<Synchronous> {}AnnotationLiteral<Synchronous> {} • When qualifiers are to be examined atWhen qualifiers are to be examined at runtime:runtime:
  28. 28. EventsEvents @@InjectInject @@EventQualifierEventQualifier privateprivate Event<SampleEvent> event;Event<SampleEvent> event; publicpublic voidvoid fireEvent() {fireEvent() { SimpleEvent()); SimpleEvent()); }} • Event observer (with the appropriate qualifier)Event observer (with the appropriate qualifier) publicpublic voidvoid observes(observes( @@ObservesObserves @@EventQualifierEventQualifier SampleEvent event) { .. }SampleEvent event) { .. } }} • Event producer, making use of generics:Event producer, making use of generics:
  29. 29. Events (2)Events (2) @@InjectInject @@Any Event<LoggedEvent> loggedEvent;Any Event<LoggedEvent> loggedEvent; publicpublic voidvoid login(user) {login(user) { LoggedEvent event =LoggedEvent event = newnew LoggedEvent(user);LoggedEvent(user); ifif (user.isAdmin()) {(user.isAdmin()) { newnew AdminLiteral()).fire(event);AdminLiteral()).fire(event); }} elseelse {{;; }} }} • Dynamic choice of qualifiersDynamic choice of qualifiers • @Observes(notifyObserver=IF_EXISTS)@Observes(notifyObserver=IF_EXISTS) notifies only if an instance of the declaringnotifies only if an instance of the declaring beanbean
  30. 30. Circular dependenciesCircular dependencies @@ApplicationScopedApplicationScoped publicpublic classclass Bean1 {Bean1 { @@InjectInject publicpublic Bean1(Bean2 bean2) {..}Bean1(Bean2 bean2) {..} }} @@ApplicationScopedApplicationScoped publicpublic classclass Bean2 {Bean2 { @@InjectInject publicpublic Bean2(Bean1 bean1) {..}Bean2(Bean1 bean1) {..} }} • CDI implementations must use proxies for allCDI implementations must use proxies for all scopes, exceptscopes, except @Dependent@Dependent
  31. 31. DemoDemo (Programatic lookup, Events, Circular Dependencies)
  32. 32. Portable extensionsPortable extensions • CDI allows plugable extensions that can access the context, hook to context events • Providing its own beans, interceptors and decorators to the container • Injecting dependencies into its own objects using the dependency injection service • Providing a context implementation for a custom scope • Augmenting or overriding the annotation- based metadata with metadata from some other source
  33. 33. Portable extensions (2)Portable extensions (2) • nsionsPackage • XML configuration • Wicket integration • JavaSE and Servlet container support
  34. 34. ConcernsConcerns • Lack of standardized XML configuration • Not many „extras“ available yet • Annotation mess • CDI interceptors might not be sufficient, compared to Spring AOP (AspectJ syntax) • (un)portable extensions may become exactly what spring is being critized for – size and complexity • Complex • Being a standard?
  35. 35. • • • • ResourcesResources
  36. 36. QuestionsQuestions??