неделя, 25 март 2012 г.

Dependency Injection in Java - JSR-330 and JSR-299

This series of articles introduce Dependency Injection in Java EE as part of Java EE 6 platform as well as different ways to use the standardized via JSR 330 and JSR 299 Java DI in non J2EE environments or older application servers not compliant with J2EE 6 as well as in J2EE 6 certified application servers.
This first article of the series discusses basic dependency injection and inversion of control concepts. It also provides a short introduction to JSR 330 and JSR 299 as well as a list of existing implementations of the JSRs. In addition a summary of application servers versions and corresponding CDI support is outlined.

Dependency Injection and Inversion of Control


This section can be skipped by readers who know the relation between the two terms Dependency Injection (DI) and Inversion of Control (IoC). I decided to write a few words because it is important to understand that IoC is the more common term and represents a design paradigm while DI is the name of a design pattern and is one of the implementation techniques used for IoC.

In general IoC is an object-oriented practice whereby the object coupling is bound at run time and is typically not known at compile time. In practice, IoC is a programming style where reusable code controls the execution of a problem-specific code and has the following benefits:Decoupling from actual implementation; Single responsibility of modules, every module can focus on its own task; Modules rely only on the contracts of external systems; Replacing modules has no side effect on other modules. Martin Fowler oulines four types of DI in its article Inversion of Control Containers and the Dependency Injection pattern:Constructor injection Setter injection Interface injection Service locator The first three are aspects of Dependency injection. According to different sources there are several additional forms of DI:Field injection Dependency lookup Factory pattern This series of articles use the term Dependency injection in the context defined so far and the term dependency injection container to denote concrete software modules that provide implementations of the DI design pattern.

Dependency Injection In Java (JSR 330 and JSR 299)


Usually a lot of confusion brings the fact that both JSR-330 (Dependency Injection for Java) led by Rod Johnson (SpringSource) and Bob Lee (Google Inc.) and JSR-299 led by Gavin King (the founder of Hibernate) became a part of Java EE 6. JSR-330 is very simplistic. It comes with own few annotations from the package: javax.inject. The package contains the following elements: Inject, Qualifier, Scope, Singleton, Named and Provider. Its the definition of the basic dependency injection semantics. In Java EE 6 you can just use JSR-330 for basic stuff, and enhance it on demand with JSR-299. CDI essentially adapts JSR-330 for Java EE environments while also adding a number of additional features useful for enterprise applications.
The JSR-299 specification defines a powerful set of complementary services that help improve the structure of application code:
A well-defined lifecycle for stateful objects bound to lifecycle contexts, where the set of contexts is extensible; A sophisticated, typesafe dependency injection mechanism, including the ability to select dependencies at either development; or deployment time, without verbose configuration; Support for Java EE modularity and the Java EE component architecture—the modular structure of a Java EE application; is taken into account when resolving dependencies between Java EE components; Integration with the Unified Expression Language (EL), allowing any contextual object to be used directly within a JSF or JSP page; The ability to decorate injected objects; The ability to associate interceptors to objects via typesafe interceptor bindings An event notification model; A web conversation context in addition to the three standard web contexts defined by the Java Servlets specification; An SPI allowing portable extensions to integrate cleanly with the container.
The services defined by this specification allow objects to be bound to lifecycle contexts, to be injected, to be associated with interceptors and decorators, and to interact in a loosely coupled fashion by firing and observing events. Various kinds of objects are injectable, including EJB 3 session beans, managed beans and Java EE resources. We refer to these objects in general terms as beans and to instances of beans that belong to contexts as contextual instances. Contextual instances may be injected into other objects by the dependency injection service. To take advantage of these facilities, the developer provides additional bean-level metadata in the form of Java annotations and application-level metadata in the form of an XML descriptor.


The use of these services significantly simplifies the task of creating Java EE applications by integrating the Java EE web tier with Java EE enterprise services. But very often in reality it is not straightforward to use these services in production environments because there some issues that have to be considered:

  • Non J2EE environment - web applications can be deployed on simple web containers like Tomcat;
  • Non J2EE 6 certified application servers - application server supports an older version of the J2EE standard;

There are probably other cases that deserve attention but let's consider those three as a starting point in this first article on DI. The first case is an example of my experience with writing web applications in Java. People used DI a long time ago before even knowing that JSR-330 and JSR-299 exist. The way we do it is using the well known Spring framework as a DI implementation. Spring provides a specific services for DI (both via XML and annotations) as well as additional enterprise services similar to JSR-299. The good news is that Spring 3.x release comes with a build-in support for the JSR-330. So it is now possible to use this annotation as an alternative for the @Autowired provided by Spring. The benefit is that JSR-330 is supported in different environments due to its various implementations:

  • J2EE 6 containers;
  • Spring 3.x
  • Guice 2.0
Implementing an application that depends only on the JSR-330 API it is possible to deploy it in J2EE 6 containers or just provide implementations like Spring or Guice in non J2EE 6 environment. Similar is the case when application server used in production supports an older J2EE version. In such cases I usually use the enterprise services provided by the supported J2EE container in combination with Spring DI. This solution will be demonstrated in the third part of these series. Of course it is possible to use CDI (JSR-299) directly by providing both the API and the corresponding JSR-299 implementation. Several JSR-299 implementations are available for use:

  • JBoss Weld
  • Apache OpenWebBeans
  • Candi

The next section provides a comprehensive information about application servers and CDI support.

CDI Support in Application Servers

Here is a table with Java EE 6 compatible implementations synchronized with Oracle's page for Java EE compatability and extended with information about the concrete CDI implementations used. The first section in the table lists Java EE 6 full profile compatible application servers while the second one is dedicated to Java EE 6 web profile compatible servers.



The table contains several additional rows with JBOSS AS that have also CDI support or require a minimum configuration to use it.

Dependency Injection and Inversion of Control