top

Friday, 10 December 2010

Understanding CDI (Contexts and Dependency Injection) Part 4

This is Fourth  part of CDI discussion.Please visit part onepart two and  part three


Interceptors
Interceptors is one feature of CDI. Using this feature we can intercept the method call. Its counterpart technique for Aspect Oriented Programming (AOP) in Spring. Its helps to analysis the business methods and these interceptors are disabled by default. so we can enable/disable the interceptor in deployment time through beans.xml  file.

Create interceptor
     To create interceptor involves two step process. first to create interceptor binding and  implement the interceptors.

here we create Log Interceptor, so we need to create Log Interceptor Binding(its  like qualifier)

Log.java

package org.ramki.interceptor;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;

/**
 *
 * @author Ramakrishnan
 */
@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface Log {
}

here @InterceptorBinding is represent that the annotation 'Log' is interceptor

second, we need to implement the interceptors

LogImpl.java
package org.ramki.interceptor.impl;

import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
import org.ramki.interceptor.Log;

/**
 *
 * @author Ramakrishnan
 */

@Interceptor
@Log

public class LogImpl {

    @AroundInvoke
    public Object logging(InvocationContext context) throws Exception
    {
        System.out.println("Log before method call...");
        Object returnObject = context.proceed();
                // to do some logging
        System.out.println("Log after method call...");
        return returnObject;
    }
}

here @Interceptor represent that its interceptor implementation
@Log specifies to which interceptor  implementation , both of these lines shows that this  class is Log interceptor Implementation

@AroundInvoke is comes before one method defines
that method must pass the below method signature

         public    Object    <methodName> (InvocationContext context)

here methodName is any name we can give.
in that method call  context.proceed() - to call actual method



so when we call any intercepted method then the container calls this method and here do pre-processing then call actual method through  context.proceed() and finally we can do some post-processing...


Apply Interceptor
Once interceptor is ready, then we can apply any business class
SimeClass.java
package org.ramki.beans;

import org.ramki.interceptor.Log;
import org.ramki.interceptor.Time;
/**
 *
 * @author Ramakrishnan
 */


@Log


public class SomeClass {

    public void methodA() {
        System.out.println("indide methodA...");
    }

    public void methodB() {
        System.out.println("indide methodB...");
    }

    public void methodC() {
        System.out.println("indide methodC...");
    }

    public void methodD() {
        System.out.println("indide methodD...");
    }

    public void methodE() {
        System.out.println("indide methodE...");
    }
}

here i put @Log in class level. we can put method level also (i.e we can put some methods )

Interceptor is disabled by default. so we need to enable through beans.xml





           
                org.ramki.interceptor.impl.LogImpl
           


Through servlet/jsp if u try to call business method of SomeClass class, its do all pre and post processing through interceptors.

Comments are welcomed 


Scree cast
please watch video in HQ mode


Comments are welcomed

Monday, 6 December 2010

Understanding CDI (Contexts and Dependency Injection) Part 3

This is Third  part of CDI discussion.Please visit first part and part two,


@Alternative
In part two we seen @qualifier 's to resolve the unambiguous problem for one interface and more than on implementation. In qualifier helps to solve in development time. (i.e all meta information is stored in class files).
Another solution is @Alternative annotation solve the problem in deployment time. all configuration is stored in beans.xml in WEB-INF folder


We take same example what we discussed in last part 


one interface (Hello) and two implementation(HelloImplOne, HelloImplTwo)
here i marked @Alternative in both implementation




Hello Interface
package org.ramki.service;

/**
 *
 * @author ramki
 */
public interface Hello {

    String sayHello(String name);
}



HelloImplOne Implementation

package org.ramki.service;

/**
 *
 * @author ramki
 */
@Alternative
public class HelloImplOne implements Hello {

    @Override
    public String sayHello(String name) {
        return "Hello, Mr "+name;
    }

}



HelloImplTwo Implementation

package org.ramki.service;

/**
 *
 * @author ramki
 */
@Alternative
public class HelloImplTwo implements Hello {

    @Override
    public String sayHello(String name) {
       return "Hi, "+name;
    }

}

and go and modify the beans.xml in WEB_INF folder



      
             org.ramki.service.HelloImplTwo
      



In <alternatives> tag in beans.xml we need specify which one need to inject.

See the screen cast for demo





Comments are welcomed

Thursday, 2 December 2010

Learning CDI (Contexts and Dependency Injection) Part 2

This is second part of CDI discussion. If u r not visited, Please visit first part,

Qualifier
           Its annotation, its helps to create our qualifier annotation. We already seen if we have more than one implementation of particular interface then we can't inject, because ambiguity issues are arise. so we need to define own qualifiers and marked the annotation with that qualifier. When inject we need to mention the qualifier.


For Example

We have one interface and two implementation

Hello Interface
package org.ramki.service;

/**
 *
 * @author ramki
 */
public interface Hello {

    String sayHello(String name);
}



HelloImplOne Implementation

package org.ramki.service;

/**
 *
 * @author ramki
 */
public class HelloImplOne implements Hello {

    @Override
    public String sayHello(String name) {
        return "Hello, Mr "+name;
    }

}



HelloImplTwo Implementation

package org.ramki.service;

/**
 *
 * @author ramki
 */
public class HelloImplTwo implements Hello {

    @Override
    public String sayHello(String name) {
       return "Hi, "+name;
    }

}

 In Injection  Point (i.e where u inject the class, i.e where u use @inject key word) if u try to inject using interface like this u get AmbiguousResolutionException.
@javax.inject.Inject Hello hello;


but we can still use like this
@javax.inject.Inject HelloImplOne hello;
@javax.inject.Inject HelloImplTwo hello;


so we need use qualifier

we can create own qulaifier like any class


package qualifies;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.inject.Qualifier;

/**
 *
 * @author ramki
 */
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Hi {

}



here
@Qualifier - is annotation to represent that we r creating custom qualifier. while deploying the container
check that class contain qualifier annotation is present. If its present container treat  class as qualifier.

@Retention(RUNTIME) - its like decision maker. this annotation decides that our annotation is present in runtime or compile time.
possible Values are (RUNTIME, CLASS, SOURCE)
RUNTIME - annotation is stored in class file and while running JVM can see the annotation is reflection API
CLASS - annotaion is stored in class file but its not visible in JVM. Its mainly used by deployment time (ie. we can inform to container)
SOURCE - this annotation is not stored in class file. its only used for inform some info to compiler. (Ex: @Override its inform to compiler this method is going to override.).

@Target({METHOD, FIELD, PARAMETER, TYPE}) - What are the places we can use our annotation. here we can use to any method, fields, parameter declaration's and any class and interface see all possible values hereso finally we create 'Hi' qualifier from above code. we use this qualifier to solve the ambiguous problem.take any class implementation from above code (here i take HelloImplTwo) and add our new qualifier 'Hi' with '@' symbol(it represent annotation)

HelloImplTwo Implementation

package org.ramki.service;

package org.ramki.service;

import qualifies.Hi;

/**
 *
 * @author ramki
 */
@Hi   // here i added our qualifier
public class HelloImplTwo implements Hello {

    @Override
    public String sayHello(String name) {
       return "Hi, "+name;
    }

}


thats its. now in injection point
if you using like this
@javax.inject.Inject Hello hello;
then Class HelloImplOne is injected.

if you using like this

@javax.inject.Inject @Hi Hello hello;
then Class HelloImplTwo is injected.


Please see the Third part here


see the Screen cast 




Please see the Third part here


Comments are welcomed
Related Posts Plugin for WordPress, Blogger...