Simplest Possible EJB 3.1 + JSR-299/JSR-330 Combination 📎
JSR-299 / JSR-330 beans can be easily combined with EJB 3.1 without any friction. The @Stateless bean:
@Path("message")
@Stateless
public class ServiceFacade {
@Inject @Message(Say.GOOD_BYE) MessageService message;
@Inject DateService dateService;
@GET public String getMessage(){
return message.getMessage() + " " + dateService.getCurrentTime();
}
}
is exposed via JSR-311 (REST) and a @GET method in particular. Two others JSR-299 beans are directly injected to the @Stateless instance. The CurrentDateService is just a class, which implements the interface DateService, without any additional annotations or configuration:
public class CurrentDateService implements DateService{
public Date getCurrentTime(){
return new Date();
}
}
The only implementation of the interface is injected with the @Inject annotation. It only works in case there is only one implementation of a particular interface (just like the @EJB annotation). The MessageService has two implementations - so a particular implementation has to be qualified. A custom annotation Message is used for this purpose:
@Qualifier
@Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Message {
enum Say{
HELLO, GOOD_BYE
}
Say value();
}
Every injectable implementation of the interface has to be annotated as well:
@Message(Message.Say.GOOD_BYE)
public class GoodByeMessageService implements MessageService{
public String getMessage() {
return "Good Bye";
}
}
EJB 3.1 are still the easiest possible choice for the implementation of services / boundaries. Convention over configuration makes any configuration really optional, and the default aspects like transactions, concurrency and request scope kill the superfluous bloat. JSR-299/JSR-330 DI exceed the EJB injection capabilities - both can be nicely combined.
The working project with source was packaged as a WAR (EJB31AndJSR299.war with the size of 16kB) and pushed into: http://kenai.com/projects/javaee-patterns/. To make the enhanced injection work, you will have to create a configuration file beans.xml located in WEB-INF with the content <beans></beans>. This actually pollutes the cleanness and conciseness of EJB 3.1, so I opened an issue :-).
An average deployment took < 300 ms. The project was tested with NetBeans 6.8 RC 1 and bundled Glassfish v3 b73.
[See also Dependency Injection Extender pattern, page 231 in "Real World Java EE Patterns Rethinking Best Practices" book for more in-depth discussion]