Tuesday, 1 February 2011

Loose Coupling using CDI

A key to n-tier architectures is notion of loose coupling and CDI enables this between classes in Java EE 6.

By using the @Inject annotation, you can specify an injection point in a class. The below example uses the annotation on a setter method.

    @Inject
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

It could equally be used on a field as below:

    @Inject
    Customer customer;

It is possible that more than one implementation of the Customer class exists so to resolve this problem at runtime, qualifiers are used. They provide the ability to 'qualify' what gets injected. an example qualifier is below:

import javax.inject.Qualifier;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Qualifier
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface TradeCustomerQualifier {
}

The TradeCustomer class would be enhanced to use the qualifier by way of an annotation.

@TradeCustomerQualifier
@Named("tradeCustomer")
@ApplicationScoped
public class TradeCustomer extends Customer {

    ......

}

An example of using the qualifier is below:

    @Inject
    public void setCustomer(@TradeCustomerQualifier Customer customer) {
        this.customer = customer;
    }


Finally, in order for CDI to bootstrap, there'll need to be a beans.xml file in the META-INF folder (for jars and in the WEB-INF for web applications.)

<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/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>