The producermethods Example: Using a Producer Method To Choose a Bean Implementation
The producermethods example shows how to use a producer method to choose between two beans at runtime, as described in Using Producer Methods, Producer Fields, and Disposer Methods in CDI Applications. It is very similar to the encoder example described in The encoder Example: Using Alternatives. The example includes the same interface and two implementations of it, a managed bean, a Facelets page, and configuration files. It also contains a qualifier type. When you run it, you do not need to edit the beans.xml file and redeploy the application to change its behavior.
Components of the producermethods Example
The components of producermethods are very much like those for encoder, with some significant differences.
Neither implementation of the Coder bean is annotated @Alternative, and the beans.xml file does not contain an alternatives element.
The Facelets page and the managed bean, CoderBean, have an additional property, coderType, that allows the user to specify at runtime which implementation to use. In addition, the managed bean has a producer method that selects the implementation using a qualifier type, @Chosen.
The bean declares two constants that specify whether the coder type is the test implementation or the implementation that actually shifts letters:
private final static int TEST = 1; private final static int SHIFT = 2; private int coderType = SHIFT; // default value
The producer method, annotated with @Produces and @Chosen as well as @RequestScoped (so that it lasts only for the duration of a single request and response), takes both implementations as arguments, then returns one or the other, based on the coderType supplied by the user.
@Produces @Chosen @RequestScoped public Coder getCoder(@New TestCoderImpl tci, @New CoderImpl ci) { switch (coderType) { case TEST: return tci; case SHIFT: return ci; default: return null; } }
Finally, the managed bean injects the chosen implementation, specifying the same qualifier as that returned by the producer method to resolve ambiguities:
@Inject @Chosen @RequestScoped Coder coder;
The Facelets page contains modified instructions and a pair of radio buttons whose selected value is assigned to the property coderBean.coderType:
<h2>String Encoder</h2> <p>Select Test or Shift, type a string and an integer, then click Encode.</p> <p>If you select Test, the TestCoderImpl bean will display the argument values.</p> <p>If you select Shift, the CoderImpl bean will return a string that shifts the letters in the original string by the value you specify. The value must be between 0 and 26.</p> <h:form id="encodeit"> <h:selectOneRadio id="coderType" required="true" value="#{coderBean.coderType}"> <f:selectItem itemValue="1" itemLabel="Test"/> <f:selectItem itemValue="2" itemLabel="Shift Letters"/> </h:selectOneRadio> ...
Running the producermethods Example
You can use either NetBeans IDE or Ant to build, package, deploy, and run the producermethods application.
To Build, Package, and Deploy the producermethods Example Using NetBeans IDE
- From the File menu, choose Open Project.
- In the Open Project dialog, navigate to:
tut-install/examples/cdi/
- Select the producermethods folder.
- Select the Open as Main Project check box.
- Click Open Project.
- In the Projects tab, right-click the producermethods project and select Deploy.
To Build, Package, and Deploy the producermethods Example Using Ant
- In a terminal window, go to:
tut-install/examples/cdi/producermethods/
- Type the following command:
ant
This command calls the default target, which builds and packages the application into a WAR file, producermethods.war, located in the dist directory.
- Type the following command:
ant deploy
To Run the producermethods Example
- In a web browser, type the following URL:
http://localhost:8080/producermethods
The String Encoder page opens.
- Select either the Test or Shift Letters radio button, type a string and
the number of letters to shift by, then click Encode.
Depending on your selection, the Result line displays either the encoded string or the input values you specified.