Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Java EE: Working with Lifecycle and @Alternative Beans Annotations

In this tutorial, you are going to see a step-by-step about how to deal with Beans Lifecycle in JEE, as well as understanding the new annotation resource of @Alternative

The Context and Dependency Injection (CDI), specified by JSR-299, is part of Java EE and provides an architecture that allows Java EE components such as servlets, enterprise beans and JavaBeans, to exist within the lifecycle of an application with well-defined scopes. In addition, CDI services allow Java EE components such as EJB session beans and JavaServer Faces (JSF) managed beans, to be injected and to interact in a loosely coupled way by firing and observing events.

This tutorial demonstrates how you can take advantage of the @Alternative annotation to configure your application for different deployments and also how to use the annotations of the managed bean life cycle, like @PostConstruct and the @PostDestroy to combine CDI injection with functionality provided by the Managed Bean Specification of Java EE (see Links section).

NetBeans IDE provides built-in support for Contexts and Dependency Injection, including the option of generating the beans.xml CDI configuration file during project creation, editor and navigation support for annotations, as well as various wizards for creating CDI artifacts commonly used.

To complete this tutorial, you need the following software and resources:

  • NetBeans IDE Java EE, version 7.2, 7.3, 7.4, 8.0
  • JDK (Java Development Kit), version 7 or 8
  • GlassFish Server, Open Source Edition 3.x or 4.x

Note: The Java EE package in NetBeans also includes the GlassFish Server Open Source Edition, which is a container compatible with Java EE.

Treating Multiple Deployments

CDI provides the use of @Aternativeannotation that allows you to encapsulate various beans that match an injection point without ambiguity errors. In other words, it can apply the @Alternative annotation to two or more beans and then, based on the deployment, specify the bean you want to use in the beans.xml CDI configuration file.

Consider the following scenario as a demonstration of that. We injected one ItemValidator in our main class ItemProcessor. The ItemValidator is implemented by DefaultItemValidator and by the RelaxedItemValidator. Based on deployment requirements, we would use DefaultItemValidator for most cases, but it is also required RelaxedItemValidator for a specific deployment. To resolve this, we annotated the two beans and then specify which bean to use for a given deployment by adding an entry to beans.xml file of the application. See Figure 1 for more details.

Figure 1. Validator Internal Structure

  • Beginning with the creation of the model from the initial design , open the IDE and creates a new Java EE project.
  • Then right-click the project node in the Projects window and choose Properties.
  • Select the Run category and confirm that the GlassFish instance is selected in the drop-down server list.
  • Create a ItemValidator interface.
  • Click the New File button or press Ctrl-N to open the File wizard.
  • Select the Java category, then select Java Interface. Click Next.
  • Enter ItemValidator as the class name and then exercise as the package.
  • Click Finish. The new interface is generated and opens in the editor.
  • Add a method called isValid() that takes an Item object and returns a boolean value, just like:
public interface ItemValidator {
    boolean isValid(Item item);
}

  • Expand the ItemProcessor class to incorporate the new functionality. Open ItemProcessor in the editor and make the following changes:

@Named
@RequestScoped public class ItemProcessor {
 @Inject @Demo private ItemDao itemDao;
 @Inject private ItemValidator itemValidator;
 public void execute() {
  List < Item > items = itemDao.fetchItems();
  for (Item item: items) {
   System.out.println("Item = " + item + " valid = " + itemValidator.isValid(item));
  }
 }
}

  • Create an implementation of ItemValidator called DefaultItemValidator that simply tests the limit on the value. In the Projects window, click the right mouse button on the package exercise and select New > Java Class. Name the class DefaultItemValidator and click Finish.
  • Have the DefaultItemValidator implementing the ItemValidator and replacing the isValid() method as follows:

public class DefaultItemValidator implements ItemValidator {
 @Override public boolean isValid(Item item) {
  return item.getValue() < item.getLimit();
 }
}

  • Click the Run Project button in the IDE's main toolbar. The project is compiled and deployed to GlassFish, and the welcome page of the application (process.xhtml) will open in the browser.
  • Click the "Run" button that appears on the page. Go back to the IDE and examine the GlassFish Server log. The server log is displayed in the Output window in the GlassFish tab. It is possible to notice that the items are being validated and the only valid item listed is the case where the value is less than the threshold:

INFO: Item = exercise.Item@e857ac [Value=34, Limit=7] valid = false
INFO: Item = exercise.Item@63124f52 [Value=4, Limit=37] valid = true 
INFO: Item = exercise2.Item@4715c34e [Value=24, Limit=19] valid = false 
INFO: Item = exercise.Item@65c95a57 [Value=89, Limit=32] valid = false

Figure 2. Output window of the test.

  • Now, consider the scenario where we have to deploy to a different site, more flexible, and consider an item as invalid only if the value is more than two times higher than the limit. You may need to have another bean that implements the interface ItemValidatorfor this logic.
  • Create a new implementation of ItemValidator called RelaxedItemValidator. In the Projects window, click the right mouse button on the package exercise and select New > Java Class. Name the class asRelaxedItemValidatorand click Finish.

Have the RelaxedItemValidator implementing the ItemValidator and replacing the isValid() method as follows:

public class RelaxedItemValidator implements ItemValidator {
 @Override public boolean isValid(Item item) {
  return item.getValue() < (item.getLimit() * 2);
 }
}

  • Click the Run Project button to run the project. Note that the project now fails to deployment.
  • Examine the server log in the Output window. You notice an error message reporting an issue of "ambiguous dependence." This is because we now have two classes implementing the same interface:

org.glassfish.deployment.common.DeploymentException: Injection point has ambiguous dependencies.
Injection point: field exercise.ItemProcessor.itemValidator; Qualifiers: [@javax.enterprise.inject.Default()]; 
Possible dependencies: [exercise.RelaxedItemValidator, exercise.DefaultItemValidator]

Weld, the implementation for CDI, can not determine whether to use the RelaxedItemValidator or DefaultItemValidator for the given injection point.

As mentioned above, the only difference is based on the deployment. For most deployments, we prefer to use the default validator, but for a deployment, we prefer to use the "flexible" implementation. The CDI offers the use of @Alternative annotation that lets you encapsulate various beans that match an injection point without ambiguity errors and the bean to be used, which is defined in beans.xml file. This allows you to deploy both implementations in the same module with beans.xml definition being the only difference, that may change over different deployments.

  • Add @Alternative annotation and import statements corresponding to RelaxedItemValidator and DefaultItemValidator. Open RelaxedItemValidator in the editor and make the following changes:

import javax.enterprise.inject.Alternative;
...

@Alternative
public class RelaxedItemValidator implements ItemValidator {
 public boolean isValid(Item item) {
  return item.getValue() < (item.getLimit() * 2);
 }
}

Figure 3. Importing @Alternative annotation

Switch to DefaultItemValidator (press Ctrl-Tab) and make the following changes:

import javax.enterprise.inject.Alternative;
...

@Alternative
public class DefaultItemValidator implements ItemValidator {
 public boolean isValid(Item item) {
  return item.getValue() < item.getLimit();
 }
}

If the application was deployed, we would now have an error message "unsatisfied dependency", since we have defined the two matching beans as alternative, but do not activate any of them in beans.xml file.

  • Use the IDEGo to File dialog box to quickly open the beans.xml file. Select Navigate > Go to File in the IDE's main menu (Alt-Shift-O), then type "beans" (like Figure 4). Click OK.

Figure 4. Go to File dialog box.

Make the following changes in bean.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<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">
   <alternatives>
      <class>exercise.RelaxedItemValidator</class>
   </alternatives>
</beans>

This tells CDI that the RelaxedItemValidator should be used for this deployment. You can find that @Alternative annotation effectively disables the bean, making it unavailable for injection, but allowing the implementation to be encapsulated with other beans. Adding it as an alternative in beans.xml file effectively restores the bean, making it available for injection. To move this kind of metadata for the beans.xml file, we can put in the package different versions of the file to multiple deployments.

  • Click the Run Project button to run the project (Alternatively, press F6). In the browser, click the "Run" button displayed on the page. Go back to the IDE and examine the GlassFish server log displayed in the Output window:

INFO: Item = exercise.Item@672f0924 [Value=34, Limit=7] valid = false
INFO: Item = exercise.Item@41014f68 [Value=4, Limit=37] valid = true 
INFO: Item = exercise.Item@3d04562f [Value=24, Limit=19] valid = true 
INFO: Item = exercise.Item@67b646f4 [Value=89, Limit=32] valid = false

Applying Lifecycle Annotations to Managed Beans

In this exercise, one ItemErrorHandler will be injected into the main ItemProcessor. As the FileErrorReporter is the only implementation of ItemErrorHandler interface, it will be selected as the injection. To configure specificlifecycleactions for the class, it must use the @PostConstruct and @PreDestroy annotations from the Managed Bean specification (included in theJSR 316: Java Platform, Enterprise Edition 6 Specification), like we see in Figure 5.

Figure 5. FileErrorReporter structure

Continuing the example, create a ItemErrorHandler interface to handle invalid items to be discovered.

  • In the Projects window, click the right mouse button on the package exercise and select New > Java Interface.
  • In the wizard Java Interface, type ItemErrorHandler as the class name, and then exercise as the package. Click Finish.
  • The new interface is generated and opens in the editor.
  • Add a method called handleItem() that takes an Item object as an argument:

public interface ItemErrorHandler {
    void handleItem(Item item); 
}

  • Start with the implementation of ItemErrorHandler with a fake handler called FileErrorReporter that saves the details of the item to a file. In the Projects window, click the right mouse button on the package exercise and select New > Java Class. Name the class as FileErrorReporterand click Finish.
  • Have the FileErrorReporter implementing the ItemErrorHandler and replacing the handlerItem() method as follows:

public class FileErrorReporter implements ItemErrorHandler {
 @Override public void handleItem(Item item) {
  System.out.println("Saving " + item + " to file");
 }
}

You want to open the file before you start treating items, so leave it open during the process in which content is added to the file, and then close the file when processing is complete. You could manually add initProcess() and finishProcess() to tell error bean, but then could not code the interface since the caller would need to know these specific methods of the class. You could add those same methods to ItemErrorReporter interface, but then it would be necessary to implement unnecessarily such methods in each class that implements that interface. Instead, you can use some of the life cycle annotations of the Managed Bean specification to call methods in the Bean at some points in the bean lifecycle. A method annotated with @PostConstruct is called when the bean has been constructed and any dependency bean has been injected. Likewise, a method annotated with @PreDestroyis called just before the bean has been discarded by the container.

  • Add the following init() and release() with the corresponding @PostConstruct and @PreDestroy annotations:

public class FileErrorReporter implements ItemErrorHandler {
 @PostConstruct public void init() {
  System.out.println("Creating file error reporter");
 }
 @PreDestroy public void release() {
  System.out.println("Closing file error reporter");
 }
 @Override public void handleItem(Item item) {
  System.out.println("Saving " + item + " to file");
 }
}

  • Fix Imports. Click the right mouse button in the editor and select Fix Imports, or press Ctrl-Shift-I. Import statements for javax.annotation.PostConstruct and javax.annotation.PreDestroy will be added to the top of the file.
  • Finally, add the new ItemErrorHandler bean to ItemProcessor:

@Named
@RequestScoped public class ItemProcessor {
 @Inject @Demo private ItemDao itemDao;
 @Inject private ItemValidator itemValidator;
 @Inject private ItemErrorHandler itemErrorHandler;
 public void execute() {
  List < Item > items = itemDao.fetchItems();
  for (Item item: items) {
   if (!itemValidator.isValid(item)) {
    itemErrorHandler.handleItem(item);
   }
  }
 }
}

Click the Run Projectbutton to run the project (Alternatively, press F6). In the browser, click the "Run" button displayed on the page. Go back to the IDE and examine the GlassFish server log displayed in the Output window:

INFO: Creating file error reporter
INFO: Saving exercise.Item@6257d812 [Value=34, Limit=7] to file 
INFO: Saving exercise.Item@752ab82e [Value=89, Limit=32] to file 
INFO: Closing file error reporter

Conclusion

Different deployment applications can use different rules for handling invalid items, such as the rejection of an item, sending notifications to individuals, the signs of these items, or simply listing them in an output file. Moreover, it is possible to make a combination of these rules (eg., To reject a request, send an email to a sales representative and list an order in a file). A great way to treat this kind of multi-faceted problem is by using events.

Links

Managed Bean Specification: https://jcp.org/en/jsr/detail?id=316



Web developer and passioned for web design, SEO and front end technologies.

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login