Contexts and Dependency Injection for Java EE (CDI) - JSR 299.
Leader: Gavin King
CDI is the de-facto API for comprehensive next-generation type-safe dependency injection for Java EE, which aims to synthesize the best-of-breed dependency injection features from solutions like Seam, Guice and Spring while adding many useful innovations of its own.
Java EE 5
What you can do is:
What you could not is:
CDI is designed to solve in a highly type-safe, consistent and portable way that fits the Java philosophy well.
Comparison with existing technologies.
CDI enhances the Java EE programming model in two more important ways - both of which come from Seam.
CDI has no component model of its own but is really a set of services that are consumed by Java EE components such as managed beans, Servlets and EJBs.
Managed beans are a key concept introduced in Java EE 6 to solve some of the limitations when using Java EE 5 style resource injection.
A managed bean is just a bare Java object in a Java EE environment. Other than Java object semantics, it has a well-defined create/destroy life-cycle that you can get callbacks for via the @PostConstruct and @PreDestroy annotations. Managed beans can be explicitly denoted via the @ManagedBean annotation, but this IS NOT ALWAYS needed, especially with CDI. From a CDI perspective, this means that almost any Java object can be treated as managed beans and so can be full participants in dependency injection.
Traditional JSF backing beans are now managed beans.
All EJB session beans are now also redefined to be managed beans with additional services (thread-safety and transactions by default).
Servlets are NOT yet redefined to be managed beans.
CDI also integrates with JSF via EL bean name resolution from view technologies like Facelets and JSP as well as automatic scope management.
CDI's integration with JPA consists of honoring the @PersistenceContext and @PersistenceUnit injection annotations, in addition to @EJB and @Resource.
Note
CDI DOES NOT directly support business component services such as transactions, security, remoting, messaging and the like that are in the scope of the EJB specification.
JSR 299 utilizes the Dependency Injection for Java (JSR 330) specification as its foundational API, primarily by using JSR 330 annotations such as @Inject, @Qualifier and @ScopeType. Led by Rod Johnson and Bob Lee, JSR 330 defines a minimalistic API for dependency injection solutions and is primarily geared towards non-Java EE environments.
CDI essentially adapts JSR 330 for Java EE environments while also adding a number of additional features useful for enterprise applications.
Dependency Injection Basics
@Stateless
public class BidService {
@Inject
private BidDao bidDao;
public void addBid (Bid bid) {
bidDao.addBid(bid);
}
}
public class DefaultBidDao implements BidDao {
@PersistenceContext
private EntityManager entityManager;
public void addBid (Bid bid) {
entityManager.persist(bid);
}
}
public interface BidDao {
public void addBid (Bid bid);
}
The bid DAO managed bean is being injected into the bid service EJB session bean via the @Inject annotation. CDI resolves the dependency by looking for any class that implement the BidDao interface. When CDI finds the DefaultBidDao implementation, it instantiates it, resolves any dependencies it has (like the JPA entity manager injected via @PersistenceContext) and injects it into the EJB bid service. Since no explicit bean scope is specified for either the service or the DAO, they are assumed to be in the implicit dependent scope.
Qualifiers are additional pieces of meta-data that narrow down a particular class when more than one candidate for injection exists.
@Stateless
public class BidService {
@Inject @JdbcDao
private BidDao bidDao;
...
}
@JdbcDao
public class LegacyBidDao implements BidDao {
@Resource(name="jdbc/ActionBazaarDB")
private DataSource dataSource;
...
}
Context Management Basics
Every object managed by CDI has a well-defined scope and life-cycle that is bound to a specific context. As CDI encounters a request to inject/access an object, it looks to retrieve it from the context matching the scope declared for the object. If the object is not already in the context, CDI will get reference to it and put it into the context as it passes the reference to the target. When the scope corresponding to the context expires, all objects in the context are removed.
Available Scope Definition
Dependent, ApplicationScoped, RequestScoped, SessionScoped, ConversationScoped
Besides the built-in scopes above, it is also possible to create custom scopes via the @Scope annotation
@Named
@RequestScoped
public class BidManager {
@Inject
private BidService bidService;
...
}
@Stateless
public class BidService {
@Inject
private BidDao bidDao;
@Inject
private BiddingRules biddingRules;
...
}
@ApplicationScoped
public class DefaultBiddingRules implements BiddingRules {
...
}
@Named annotation makes the bid manager accessible from EL.
JSR 330 defines a minimalistic API for dependency injection solutions and is primarily geared towards non-Java EE environments. In particular, it does not define scope types common in server-side Java such as request, session and conversation. It also does not define specific integration semantics with Java EE APIs like JPA, EJB and JSF.
No comments:
Post a Comment