How to deploy this project ?

 

The simplest way to run this project you need to use JBoss 6 which ships with Weld CDI compatible implementation.

Download JBoss AS

However Weld also runs in servlet engines like Tomcat and Jetty, or even in a plain Java SE environment.

 

Structure of the Project:

 

This is how your Web project should look like:

CDIExample.war
¦   example.xhtml
¦
+---WEB-INF
¦   beans.xml
¦   faces-config.xml
¦   web.xml
¦
+---lib
+---sample
      Clock.class
      User.class

You might have noticed the beans.xml file. This file is required by CDI for using special features of CDI
(like Alternatives, Decorators and others). In our case, just add an empty file named beans.xml.

When executing the web application, you will see that, hitting the button, the EJB will display on your Faces message field the name you typed in the field user.name.

Letting the container create objects:
Using the @Produces annotation you can delegate to the container (instead of the application) the responsibility to create new objects.

By using producer methods let us (among others)

 

  • Expose a JPA entity as a bean,
  • Expose any JDK class as a bean,
  • Define multiple beans, with different scopes or initialization, varying the implementation of a bean type at runtime.


Let's see how to integrate this with out example. Add a new class named Factory to your application:

package sample;

import java.io.Serializable;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

 @ApplicationScoped
 public class Factory implements Serializable {
 private static final long serialVersionUID = -7213673465118041882L;
 
 @Inject User user;  
 
 @Produces @Time String printTime() {
 return user.getName() + " it is now " + new java.util.Date().toString();
 }
 

}

The @ApplicationScoped is the broadest scope which can be set for a bean. It corresponds roughly to the "application" scope of a Web application. (The other scopes allowed are  @RequestScoped, @SessionScoped and @ConversationScoped)

Here we are using the @Produces annotation along with the @Time annotation. @Time is a qualifier annotation which can be used to specify exactly which bean should be injected. (By using a qualifier annotation you can switch the bean implementation at runtime).

In our example, all we have to do is creating a class sample.Time which contains a bare bone definition of an annotation
package sample;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.inject.Qualifier;
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, METHOD, FIELD})
@Qualifier

public @interface Time { }

Think about qualifiers like an extension of the interface. It does not create a direct dependency to any particular implementation. There may be multiple alterative implementations of @Time.

Now, having moved the (silly) "logic" into the class Factory, how does our EJB changes ? simply you have to inject the
@Time annotation (produces by Factory.java) and that's all:
public class Clock {

 @Inject @Time String time;
 public void action() {

 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(time));
 }

}

Seam vs CDI


The reader who has been playing with Seam framework, will surely found some similar concepts and,in some parts, the CDI implementation is exaclty borrowed from Seam. There are however some differences with Seam

The most important difference is that Seam uses a string-based approach to bind components which is not type safe. On the other hand CDI brings type safety to the limit.

For example, in Seam you would use:

@Name("sampleBean")
public class SampleBean {
 ...
}

While in CDI you would rather use the type-safe :
public class Bean2 {
 @Inject
 private Bean1 bean1;
 ...
}

Also Seam has annotation an (@Factory) which tells Seam to create an instance of a Bean and invoke a method to initialize the value. However you cannot use this annotation to switch the implementation at runtime.

References: http://docs.jboss.org/weld/reference/1.0.0/en-US/html/

0
0
0
s2smodern