main website home
  • About this blog

    This blog features updates, opinions, and technical notes from Caucho engineers about Caucho products, the enterprise Java industry, and PHP. Caucho Technology is the creator of the Resin Application Server and the Quercus PHP in Java engine. A leader in Java performance since 1998, Caucho is a Sun JavaEE licensee with over 9000 customers worldwide.
  • Tags

    ajaxworld bam candi cdi cloud cluster comet configuration deploy devoxx eclipse ejb embedded flash flex google app engine hessian hmtp ioc java ee 6 javaone javazone jms messaging newsletter nyjug osgi php pomegranate quercus resin resin 4.0 REST servlet sfjug silicon valley code camp spring testing training tssjs watchdog webbeans web profile websockets wordpress
  • Meta

    • Register
    • Log in
    • Entries RSS
    • Comments RSS
    • WordPress.org
« Are you using Quercus?
Giving Thanks »

multiple bean injection in WebBeans

In my last post, I selected a webbeans implementation out of several drivers, but only one active ATMTransport bean at a time. If I need multiple beans, I need a way to choose the instances I want. In WebBeans, the @BindingType annotations select an active implementation. Like the previous posts, this example is based on Rick Hightower’s DI introduction.

WebBeans encourages semantically-meaningful annotations to organize and document code, and the @BindingType follows this philosophy. If I have two ATMTransport beans, there must be a reason, and I really ought to document that reason in my code. In this case, I’ll use one transport as a backup. If the standard implementation doesn’t connect to the bank, I’ll try again with the backup. So, I’ll create a new @Backup annotation for the backup ATMTransport, and continue to use @Current for the primary ATMTransport.

@Current is just a predefined @BindingType with the implicit meaning of the primary bean of a given type. So I can use @Current instead of creating a new binding type with the same meaning. @Current is only special because its is the default binding type when no others are defined. Otherwise, it’s treated exactly as any other binding.

class ATMImpl {
  @Current ATMTransport _transport;
  @Backup ATMTransport _backupTransport;
  ...
}

It’s important that I’ve created meaningful role annotations for my transport, not just names. My ATMImpl doesn’t care about the ATMTransport name; it only cares how that transport can help. In the XML, I’ll bind my selected implementation driver to the binding annotation. In this case, I’ll select a SoapATMTransport for the backup. I could also create a second StandardATMTransport with different configuration.

<WebBeans xmlns="urn:java:javax.webbeans"
              xmlns:example="urn:java:example">

  <example:SimpleATMTransport>
    <Production/>
  </example:SimpleATMTransport> 

  <example:SoapATMTransport>
    <example:Backup/>
    <example:url>https://mybank.com/atm</example:url>
    <Production/>
  </example:SoapATMTransport>

</WebBeans>

In the XML configuration, the example:Backup is my @example.Backup annotation, and example:url is a bean property. The <example:Backup/> annotates the SoapATMTransport just as if I had a @Backup annotation on the class itself. Notice, by the way, that none of the beans so far have any names at all. Since the matching is done by the bean types and the set of binding annotations, it’s impossible to match the wrong name with the wrong type, i.e. WebBeans is type safe.

When Resin injects the _backupTransport field, it looks for all the ATMTransport definitions with a @Backup annotation. If it can’t find one, it will report an error.

The @Backup definition itself is an annotation which has the @BindingType meta-annotation. Now, it is a small bit of extra work to create the annotation, but I can use it to document my intention by the annotation name and by any extra discussion in the JavaDoc. Since the @Binding annotation is also used for the XML configuration, I also get automatic validation in case I misspell it as <example:Backrup/>. Plus, my XML gets documented automatically by the JavaDoc.

package example;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
import javax.webbeans.BindingType;

@BindingType
@Documented
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Backup {
}

Revisiting @Disabled as a @BindingType

In the previous post, I used a @Disabled and @Mock as a @DeploymentType to disable the ATMTransports unless I configured them in the XML. I can rewrite @Disabled as a @BindingType to accomplish the same thing. If the drivers are marked with the @Disabled binding type, they will never match any injection (unless the injection uses @Disabled itself, which would be silly.)

package example;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
import javax.webbeans.BindingType;

@BindingType
@Documented
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Disabled {
}

Rewriting @Disabled as a @BindingType would slightly simplify my XML, since I could skip the <Production> tag.

<WebBeans xmlns="urn:java:javax.webbeans"
              xmlns:example="urn:java:example">

  <example:SimpleATMTransport>
    <Current/>
  </example:SimpleATMTransport> 

  <example:SoapATMTransport>
    <example:Backup/>
    <example:url>https://mybank.com/atm</example:url>
  </example:SoapATMTransport>

</WebBeans>

Conclusion

Now that I’ve introduced the basic injection, @BindingType, @DeploymentType, and the XML configuration, there should be enough WebBeans background to make some initial comparisons with Hightower’s Spring-based examples in a following post.

This entry was posted on Wednesday, November 19th, 2008 at 11:48 am and is filed under Engineering. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

You must be logged in to post a comment.


Caucho Technology is proudly powered by WordPress and Quercus®
Entries (RSS) and Comments (RSS).

  • HOME |
  • CONTACT US |
  • DOCUMENTATION |
  • BLOG |
  • WIKI 4 |
  • WIKI 3 |
  • Resin: Java Application Server
Copyright (c) 1998-2012 Caucho Technology, Inc. All rights reserved.
caucho® , resin® and quercus® are registered trademarks of Caucho Technology, Inc.
resin® is a cloud optimized, java® application server that supports the java ee webprofile ®