J2ee standards > CDI


Published on

Published in: Technology, Education
1 Comment
  • http://dbmanagement.info/Tutorials/Java.htm
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

J2ee standards > CDI

  1. 1. CDI<br />Contexts and Dependency Injection<br />CDI, formerly known as JSR 299, is an attempt at describing a true standard on Dependency Injection. <br />
  2. 2. Introduction<br />CDI is the Java standard for dependency injection (DI) and interception (AOP). <br />CDI is similar to core Spring and Guice frameworks. Like JPA did for ORM, CDI simplifies and sanitizes the API for DI and AOP.<br />
  3. 3. CDI to manage the dependencies<br />CDI needs an bean.xml file to be in META-INF of your jar file or classpath or WEB-INF of your web application. This file can be completely empty.<br />Use the @Inject annotation to annotate a setXXXsetter method in injected class<br />
  4. 4. @Inject<br />By default, CDI would look for a class that implements the ATMTransport interface, once it finds this it creates an instance and injects this instance of ATMTransport using the setter method setTransport. If we only had one possible instance of ATMTransport in our classpath, we would not need to annotate any of the ATMTransport implementations. Since we have three, namely, StandardAtmTransport, SoapAtmTransport, and JsonAtmTransport, we need to mark two of them as @Alternatives and one as @Default. <br />public class AutomatedTellerMachineImpl implements AutomatedTellerMachine {                private ATMTransport transport;        @Inject        public void setTransport(ATMTransport transport) {                this.transport = transport;        }      }<br />Using @Inject to inject via constructor args and fields<br />@Inject public AutomatedTellerMachineImpl(ATMTransport transport) {                this.transport = transport;}<br />
  5. 5. @Default and @Alternative<br />Use the @Default annotation to annotate the StandardAtmTransport<br />@Defaultpublic class StandardAtmTransport implements ATMTransport{<br />Use the @Alternative to annotate the SoapAtmTransport, and JsonRestAtmTransport.<br />@Alternativepublic class JsonRestAtmTransport implements ATMTransport {<br />
  6. 6. @Named<br />The @Named annotation is used by JEE 6 application to make the bean accessible via the Unified EL (EL stands for Expression language and it gets used by JSPs and JSF components).<br />@Named("atm")public class AutomatedTellerMachineImpl implements AutomatedTellerMachine{<br />It should be noted that if you use the @Named annotations and don't provide a name, then the name is the name of the class with the first letter lower case so this: makes the name automatedTellerMachineImpl.<br />
  7. 7. @Produces<br />Instead of relying on a constructor, you can delegate to a factory class to create the instance. To do this with CDI, you would use the @Produces from your factory class as follows:<br />public class TransportFactory{                        @Produces ATMTransportcreateTransport() {                System.out.println("ATMTransport created with producer");                return new StandardAtmTransport();        }}<br />On calling @Inject   private ATMTransport transport; it calls the factory method.<br />
  8. 8. Defining @Alternative <br />The @Alternative CDI annotation allows you to have multiple matching dependencies for a given injection point. This means you can define beans that provide implementations for the same interface without worrying about ambigious dependency errors. When you mark a class with the @Alternative annotation, it is effectively disabled and cannot be considered for injection. The only exception is for the class that is defined in the beans.xml configuration file. <br /><beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/beans_1_0.xsd"><br />        <alternatives>                <class>org.cdi.advocacy.JsonRestAtmTransport<br /> </class>        </alternatives><br /></beans><br />Once this bean is identified, it is then used in any injection point that matches for this bean. No other beans for similar injection points can be declared as the ‘active’ alternative.<br />
  9. 9. @Qualifier<br />All objects and producers in CDI have qualifiers. If you do not assign a qaulifier it by default has the qualifier @Default and @Any.<br />You may decide that at times you want to inject Soap or Json or the Standard transport. You don't want to list them as an alternative.<br />Qualifiers can be used to discriminate exaclty what gets injected. You can write custom qualifiers. <br />@Qualifier @Retention(RUNTIME) @Target({TYPE, METHOD, FIELD, PARAMETER})public @interface Soap {}<br />@Soappublic class SoapAtmTransport implements ATMTransport {<br />
  10. 10. Injecting SoapAtmTransport using new @Soap qualifier via constructor arg<br />@Inject public AutomatedTellerMachineImpl(@Soap ATMTransport transport) {                this.transport = transport;        }<br />OR<br />@Inject @Soapprivate ATMTransport transport;<br />
  11. 11. Class uses two qualifiers<br />@SuperFast @StandardFrameRelaySwitchingFlubberpublic class SuperFastAtmTransport implements ATMTransport {        public void communicateWithBank(byte[] datapacket) {                System.out.println("communicating with bank via the Super Fast transport " );        }}<br />Usage :<br />@Inject @SuperFast @StandardFrameRelaySwitchingFlubberprivate ATMTransport transport;<br />
  12. 12. To solve Explosion of Qualifiers<br />CDI allows you to discriminate on members of a qualifier to reduce the explosion of qualifiers. Instead of having three qualifier you could have one qualifier and an enum. Then if you need more types of transports, you only have to add an enum value instead of another class. <br />Let's demonstrate how this works by creating a new qualifier annotation called Transport. The Transport qualifier annotation will have a single member, an enum called type. The type member will be an new enum that we define called TransportType. <br />@Qualifier @Retention(RUNTIME) @Target({TYPE, METHOD, FIELD, PARAMETER})public @interface Transport {        TransportType type() default TransportType.STANDARD;}<br />public enumTransportType {        JSON, SOAP, STANDARD;}<br />Usage : <br />@Transport(type=TransportType.SOAP)public class SoapAtmTransport implements ATMTransport {<br /> @Inject @Transport(type=TransportType.STANDARD)private ATMTransport transport;<br />
  13. 13. Advanced: Using @Produces and InjectionPoint<br />@Inject @TransportConfig(retries=2)private ATMTransport transport;<br />@Produces ATMTransportcreateTransport(InjectionPointinjectionPoint) {<br />                Bean<?> bean = injectionPoint.getBean();TransportConfigtransportConfig = Bean.getBeanClass().getAnnotation (TransportConfig.class);StandardAtmTransport transport = new StandardAtmTransport();                transport.setRetries(transportConfig.retries());return transport;<br />}<br />
  14. 14. @Nonbinding<br />Using @Nonbinding to combine a configuration annotation and a qualifier annotation into one annotation<br />For e.g. - Transport qualifier annotation using @Nonbinding to add configuration retries param.<br />
  15. 15. @Any<br />@Any finds all of the transports in the system. <br />Once you inject the instances into the system, you can use the select method of instance to query for a particular type. <br />@Inject @Any private Instance<ATMTransport> allTransports;<br />@PostConstruct        protected void init() {                transport = allTransports.select(new AnnotationLiteral<Default>(){}).get();                                if (transport!=null) {                        System.out.println("Found standard transport");                        return;                }                                transport = allTransports.select(new AnnotationLiteral<Json>(){}).get();                                if (transport!=null) {                        System.out.println("Found JSON standard transport");                        return;                }                                transport = allTransports.select(new AnnotationLiteral<Soap>(){}).get();                                                if (transport!=null) {                        System.out.println("Found SOAP standard transport");                        return;                }}<br />
  16. 16. @Decorator<br />Java EE 6 lets us create decorators through CDI, as part of their AOP features. If we want to implement cross cutting concerns that are still close enough to the business, we can use this feature of Java EE 6.<br />@Decorator public class TicketServiceDecorator implements TicketService { <br /> @Inject @Delegate private TicketServiceticketService; <br /> @Inject private CateringServicecateringService; <br /> @Override public Ticket orderTicket(String name) { <br /> Ticket ticket = ticketService.orderTicket(name);<br />cateringService.orderCatering(ticket); return ticket;<br /> }<br />}<br />
  17. 17. Injecting Java EE resources into a bean<br />All managed beans may take advantage of Java EE component environment injection using @Resource, @EJB, @PersistenceContext, @PeristenceUnit, @PostConstruct and @PreDestroy and @WebServiceRef.<br />Example :<br />@Transactional @Interceptor public class TransactionInterceptor {    @Resource UserTransaction transaction; <br />   @AroundInvoke public Object manageTransaction(InvocationContext ctx) throws Exception { ... } }<br />@SessionScopedpublic class Login implements Serializable { <br />   @Inject Credentials credentials;    @PersistenceContext EntityManager userDatabase;     }<br />
  18. 18. Dirty truth<br />CDI is part of JEE 6. It could easily be used outside of a JEE 6 container. The problem is that there is no standard interface to use CDI outside of a JEE 6 container so the three main implementations Caucho Resin Candi, Red Hat JBoss Weld and Apache OpenWebBeans all have their own way to run a CDI container standalone. <br />
  19. 19. Conclusion<br />Dependency Injection (DI) refers to the process of supplying an external dependency to a software component. <br />CDI is the Java standard for dependency injection and interception (AOP). It is evident from the popularity of DI and AOP that Java needs to address DI and AOP so that it can build other standards on top of it. DI and AOP are the foundation of many Java frameworks.<br />