With the addition of annotations in JDK 5 and EJB3 in J2EE, I think we have an opportunity to totally ditch XML-based configuration. This includes EJB deployment descriptors and XML-based IoC "lightweight" containers. So how will you do fine-grain configuration of your components? How will you do the Inversion of Control that you-all just can't live without? This is what I want to talk about in this blog.

The Pico Container/Nanning guys put out an interesting concept awhile ago. Why do you have to use XML to configure your components/interceptors/aspects? Why not configure your services and components within pure Java? Configuring things in pure Java allows you to let the Java compiler typecheck your configuration. Sometimes, with XML you have to wait until deploy time/runtime to see if your XML document is valid. This kind of pure-Java-configuration can be done using EJB3 with inheritance, constructors, method overrides, and annotations.

 

Plain classes as base

The key is to model your beans as plain classes at first. These plain classes will be the base for all your service beans. Let's define a Stateless Bean that is will be used to confirm orders in an e-commerce application via email.

 

@javax.ejb.Local

public interface OrderConfirmation {

   public void sendOrderConfirmation(String to, Order order);

}

 

 

public class OrderConfirmationService implements OrderConfirmation

{

   private String from;

   private String subject;

   private MessageStyle style;

   private javax.mail.Session mailer;

 

   public (String from, String subject, MessageStyle style) {

      this.from = from;

      this.subject = subject;

      this.style = style;

   }

   

 

   public void setMailer(Session session) {

      this.mailer = session;

   }

 

   

   

   @MethodPermission({"customer"})

   public void sendOrderConfirmation(Order order) {

      Message msg = createMessage(mailer, style, 

                                    from, subject, order);

 

      Transport.send(msg);

   }

 

   private static createMessage(...) {...}

}

 



So above we have a security constraint set on our bean method and 4 configurable properties.

  • From and subject are self-explanatory.
  • style is a pojo that defines how our email message will look.
  • mailer is a reference to our Mail session. A reference to a service


 

Configuring with Inheritance

In this example, we are defining a stateless bean for order confirmation for each one of the business units of our e-commerce application. We will use constructors and method overrides to modify the configuration.

 

@Stateless

public class ToyStoreOrderConfirmationBean extends OrderConfirmationService

{

   public ToyStoreOrderConfirmationBean() {

      super("bozo.clown@toys.com", 

             "Your Toy Order Confirmation",

                new ToyStoreMessageStyle());

   }

 

   @Inject("java:/Mail")

   public void setMailer(Session session) {

      super.setMailer(session);

   }

 

   @MethodPermission({"ValuedCustomer"})

   public void sendOrderConfirmation(Order order) {

      super.sendOrderConfirmation(order);

   }

           

}



So, the constructor is used to set the configurable objects. We override the setMailer method and inject the Mail Service via the EJB3 @Inject annotation. We only allow "ValuedCustomer"s to get an email confirmation by overriding sendOrderConfirmation and retagging it with a new @MethodPermission.

 

Disadvantages

Ok, so I lied...So you can't use this approach for everything. Here's some example:
  • You can't use this approach for Entity beans. Entity beans are POJOs in EJB3 and must be allocated with with the new operator. So, if you need to override persistence mappings per deployment, you'll have to use XML.
  • There's really no standard way of configuring domain objects like MessageStyles and sharing this standard configuration between various components.


Anyways, that's it for now...

Happy hunting,

Bill