Squeezing the Most Out of the Ajax Control Toolkit's Accordion Tool | 4 | WebReference

Squeezing the Most Out of the Ajax Control Toolkit's Accordion Tool | 4


Set Up Lifecycle-specific Actions for Injected Objects

In the above example, you have applied the @PostConstruct and @PreDestroy annotations to a CDI managed bean, named BallBean. In this section, you will apply these annotations to another CDI managed bean, named RandomGenerator that will be injected into the BallBean with the @Inject annotation. The idea is to separate the generation process from the main bean by writing a producer method.

A producer method is a method that acts as a source of bean instances. The method declaration itself describes the bean and the container invokes the method to obtain an instance of the bean when no instance exists in the specified context. A producer method lets the application take full control of the bean instantiation process. A producer method is declared by annotating a method of a bean class with the @Produces annotation.

Next, you will write a producer method that returns a random value. This value will be injected into BeanBall. The RandomGenerator in this case, looks like below:

package com.games.balls;
import java.util.Random;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
public class RandomGenerator {
    private Random generator;
    private void startGenerator() {
        System.out.println("*** RANDOM GENERATOR CREATED ***");
        generator = new Random();
    private void stopGenerator() {
        System.out.println("*** RANDOM GENERATOR DESTROYED ***");
        generator = null;
      @Produces int getRandomNumber() {
      return generator.nextInt(3);

Moreover, the BallBean is modified as follows:

package com.games.balls;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
public class BallBean {
    private String ballType;
    @Inject int randomValue;
    public void generateRandomBall() {        
        switch (randomValue) {
            case 1:
                this.ballType = "Tennis Ball";
                System.out.println("*** Tennis Ball Generated ***");
            case 2:
                this.ballType = "Volley Ball";
                System.out.println("*** Volley Ball Generated ***");
            case 3:
                this.ballType = "Football Ball";
                System.out.println("*** Football Ball Generated ***");
                this.ballType = "No Ball";
                System.out.println("*** No Ball Generated ***");
    public String getBallType() {
        return ballType;
    public void setBallType(String ballType) {
        this.ballType = ballType;

A possible output of the GlassFish logs is listed below:

[#|2011-01-11T02:06:36.165-0800|INFO|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=31;_ThreadName=Thread-1;|*** RANDOM GENERATOR CREATED ***|#]
[#|2011-01-11T02:06:36.165-0800|INFO|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=31;_ThreadName=Thread-1;|*** No Ball Generated ***|#]
[#|2011-01-11T02:06:36.173-0800|INFO|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=31;_ThreadName=Thread-1;|*** RANDOM GENERATOR DESTROYED ***|#]
[#|2011-01-11T02:06:36.691-0800|INFO|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=31;_ThreadName=Thread-1;|*** RANDOM GENERATOR CREATED ***|#]
[#|2011-01-11T02:06:36.692-0800|INFO|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=31;_ThreadName=Thread-1;|*** Tennis Ball Generated ***|#]
[#|2011-01-11T02:06:36.700-0800|INFO|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=31;_ThreadName=Thread-1;|*** RANDOM GENERATOR DESTROYED ***|#]

You can see how the injected random generator is created and destroyed by the @PostConstruct and @PreDestroy annotations.

If a scope is not explicitly specified, then the bean belongs to a special scope called the dependent pseudo-scope. Beans with this scope live to serve the object into which they were injected, which means their lifecycle is bound to the lifecycle of that object.

An interesting exercise is to place the BallBean in SessionScope and the RandomGenerator on the RequestScope. Also, add to the BallBean two methods annotated with @PostConstruct and @PreDestroy. In the GlassFish logs, you will see how the lifecycle of the two beans are managed depending on their scope. In addition, you can play with different kind of scopes and injections.

Original: January 28, 2011