Jakarta Contexts and Dependency Injection defines a powerful set of complementary services that help to 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 Jakarta EE modularity and the Jakarta EE component architecture - the modular structure of a Jakarta EE application is taken into account when resolving dependencies between Jakarta EE components
-
Integration with the Unified Expression Language (EL), allowing any contextual object to be used directly within a Jakarta Server Faces or Jakarta Server Pages 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 Jakarta Servlets specification
-
An SPI allowing portable extensions to integrate cleanly with the container
For instance the following class defines a CDI bean and inject user credentials and Jakarta Persistence entity manager. It produces another bean of type User with qualifier @LoggedIn
@SessionScoped @Model public class Login implements Serializable { @Inject Credentials credentials; @Inject @Users EntityManager userDatabase; private CriteriaQuery<User> query; private Parameter<String> usernameParam; private Parameter<String> passwordParam; private User user; @Inject void initQuery(@Users EntityManagerFactory emf) { CriteriaBuilder cb = emf.getCriteriaBuilder(); usernameParam = cb.parameter(String.class); passwordParam = cb.parameter(String.class); query = cb.createQuery(User.class); Root<User> u = query.from(User.class); query.select(u); query.where( cb.equal(u.get(User_.username), usernameParam), cb.equal(u.get(User_.password), passwordParam) ); } public void login() { List<User> results = userDatabase.createQuery(query) .setParameter(usernameParam, credentials.getUsername()) .setParameter(passwordParam, credentials.getPassword()) .getResultList(); if ( !results.isEmpty() ) { user = results.get(0); } } public void logout() { user = null; } public boolean isLoggedIn() { return user!=null; } @Produces @LoggedIn User getCurrentUser() { if (user==null) { throw new NotLoggedInException(); } else { return user; } } }
CDI provides far more features. More example can be found in the existing specification document.