9 Using Contexts and Dependency Injection for the Jakarta EE Platform
This chapter includes the following sections:
- About CDI for the Jakarta EE Platform
CDI for the Jakarta EE Platform specification was formerly called Web Beans. CDI injection simplifies the use of managed beans with JSF technology in Web applications. - Defining a Managed Bean
A managed bean is the basic component in a CDI application and defines the beans that CDI can create and manage. - Injecting a Bean
To use the beans that you define, inject them into another bean that an application such as a Jakarta Server Faces can use. - Defining the Scope of a Bean
The scope of a bean defines the duration of a user's interaction with an application that uses the bean. To enable a Web application to use a bean that injects another bean class, the bean must be able to hold state over the duration of the user's interaction with the application. - Overriding the Scope of a Bean at the Point of Injection
Overriding the scope of a bean at the point of injection enables an application to request a new instance of the bean with the default scope@Dependent
. The@Dependent
scope specifies that the bean's life cycle is the life cycle of the object into which the bean is injected. - Using Qualifiers
Qualifiers enable you to provide more than one implementation of a particular bean type. - Providing Alternative Implementations of a Bean Type
The environments for the development, testing, and production deployment of an enterprise application may be very different. Differences in configuration, resource availability, and performance requirements may cause bean classes that are appropriate to one environment to be unsuitable in another environment. By providing alternative implementations of a bean type, you can modify an application at deployment time to meet such differing requirements. - Applying a Scope and Qualifiers to a Session Bean
CDI enables you to apply a scope and qualifiers to a session bean. - Using Producer Methods, Disposer Methods, and Producer Fields
A producer method is a method that generates an object that can then be injected. A disposer method enables an application to perform customized cleanup of an object that a producer method returns. A producer field is a field of a bean that generates an object. - Initializing and Preparing for the Destruction of a Managed Bean
CDI managed bean classes and their superclasses support the annotations for initializing and preparing for the destruction of a managed bean. - Intercepting Method Invocations and Life Cycle Events of Bean Classes
Intercepting a method invocation or a life cycle event of a bean class interposes an interceptor class in the invocation or event. When an interceptor class is interposed, additional actions that are defined in the interceptor class are performed. - Decorating a Managed Bean Class
Decorating a managed bean class enables you to intercept invocations of methods in the decorated class that perform operations with business semantics. - Assigning an EL Name to a CDI Bean Class
EL enables components in the presentation layer to communicate with managed beans that implement application logic. - Defining and Applying Stereotypes
In a large application in which several beans perform similar functions, you may require the same set of annotations to be applied to several bean classes. Defining a stereotype requires you to define the set of annotations only once. - Using Events for Communications Between Beans
Events enable beans to communicate information without any compilation-time dependency. - Injecting a Predefined Bean
Predefined beans are injected with dependent scope and the predefined default qualifier@Default
. - Injecting and Qualifying Resources
Java EE 5 resource injection relies on strings for configuration. Typically, these strings are JNDI names that are resolved when an object is created. CDI ensures type-safe injection of beans by selecting the bean class on the basis of the Java type that is specified in the injection point. - Using CDI With JCA Technology
WebLogic Server supports CDI in embedded resource adapters and global resource adapters. To enable a resource adapter for CDI, provide abeans.xml
file in theMETA-INF
directory of the packaged archive of the resource adapter. - Configuring a CDI Application
Configuring a CDI application enables CDI services for the application. You must configure a CDI application to identify the application as a CDI application. No special declaration, such as an annotation, is required to define a CDI managed bean. And no module type is defined specifically for packaging CDI applications. - Enabling and Disabling CDI
CDI for a domain is enabled by default. However, even when an application does not use CDI, there is some CDI initialization that occurs when you deploy an application in WebLogic Server. To maximize deployment performance for applications that do not use CDI, you can disable CDI. - Implicit Bean Discovery
CDI 1.1 and Java EE 7 introduced the concept of implicit bean archives. An implicit bean archive is an archive of a JAR or a WAR file that does not contain abeans.xml
file; it contains beans that can be managed by CDI. - Supporting Third-Party Portable Extensions
CDI is intended to be a foundation for frameworks, extensions, and integration with other technologies. - Using the Built-in Annotation Literals
CDI 2.0 introduces new built-in annotation literals that can be used for creating instances of annotations. - Using the Configurator Interfaces
CDI 2.0 introduced some new configurator interfaces which can be used for dynamically defining or modifying CDI objects. - Bootstrapping a CDI Container
CDI 2.0 provides the standard API for bootstrapping a CDI container in Java SE. You must explicitly bootstrap the CDI container using theSeContainerInitializer
abstract class and its static methodnewInstance()
.
About CDI for the Jakarta EE Platform
CDI for the Jakarta EE Platform specification was formerly called Web Beans. CDI injection simplifies the use of managed beans with JSF technology in Web applications.
CDI is specified by Java Specification Request (JSR) 365: Contexts and Dependency Injection for the Java 2.0. CDI uses the following related specifications:
-
Jakarta EE 8 Managed Beans Specification, which is a part of JSR 366: Java Platform, Enterprise Edition 8 (Java EE 8) Specification
-
Interceptors specification, which is a part of JSR 345: Enterprise JavaBeans 3.2
CDI provides the following features:
-
Contexts. This feature enables you to bind the life cycle and interactions of stateful components to well-defined but extensible life cycle contexts.
-
Dependency injection. This feature enables you to inject components into an application in a type-safe way and to choose at deployment time which implementation of a particular interface to inject.
CDI is integrated with the major component technologies in Jakarta EE, namely:
-
Servlets
-
Jakarta Server Pages (JSP)
-
Jakarta Server Faces (JSF)
-
Jakarta Enterprise Beans (EJB)
-
Jakarta EE Connector architecture (JCA)
-
Web services
Such integration enables standard Jakarta EE objects, such as Servlets and EJB components, to use CDI injection for dependencies. CDI injection simplifies, for example, the use of managed beans with JSF technology in Web applications.
See Introduction to Contexts and Dependency Injection for the Java EE Platform in the Java EE 8 Tutorial.
CDI 2.0 Examples
-
Asynchronous Events – Demonstrates how to produce async events and how singleton EJBs can consume these events.
-
Observer Ordering – Demonstrates how singleton EJBs can consume events according to the priority.
-
Interception Factory – Demonstrates how to produce a class instance with adding the specified annotation dynamically by InterceptionFactory.
For more information, see the CDI 2.0 examples in the WebLogic Server distribution kit: Oracle_HOME\wlserver\samples\server\examples\src\examples\javaee8\cdi
where ORACLE_HOME
represents the directory in which you installed WebLogic Server. See Sample Applications and Code Examples in Understanding Oracle WebLogic Server.
CDI 1.1 Example
A Java EE 7 example that show how to use CDI is provided in the CDI sample application, which is installed inOracle_HOME\wlserver\samples\server\examples\src\examples\javaee7\cdi
where ORACLE_HOME
represents the directory in which you installed WebLogic Server. See Sample Applications and Code Examples in Understanding Oracle WebLogic Server.
Defining a Managed Bean
A managed bean is the basic component in a CDI application and defines the beans that CDI can create and manage.
A bean is a source of the objects that CDI can create and manage. See About Beans in The Java EE 8 Tutorial.
To define a managed bean, define a top-level plain old Java object (POJO) class that meets either of the following conditions:
-
The class is defined to be a managed bean by any other Jakarta EE specification.
-
The class meets all of the conditions that are required by JSR 346 as listed in About CDI Managed Beans in The Java EE 8 Tutorial.
Note:
No special declaration, such as an annotation, is required to define a managed bean. To make the managed beans of an application available for injection, you must configure the application as explained in Configuring a CDI Application.
Injecting a Bean
To use the beans that you define, inject them into another bean that an application such as a Jakarta Server Faces can use.
See Injecting Beans in The Java EE 8 Tutorial.
CDI ensures type-safe injection of beans by selecting the bean class on the basis of the Java type that is specified in the injection point, not the bean name. CDI also determines where to inject a bean from the Java type in the injection point.
In this respect, CDI bean injection is different than the resource injection that was introduced in the Java EE 5 specification, which selects the resource to inject from the string name of the resource. For example, a data source that is injected with the javax.annotation.Resource annotation is identified by its string name.
To inject a bean, obtain an instance of the bean by creating an injection point in the class that is to use the injected bean. Create the injection point by annotating one of the following program elements with the javax.inject.Inject
annotation:
-
An instance class field
-
An initializer method parameter
-
A bean constructor parameter
Example 9-1 shows how to use the @Inject
annotation to inject a bean into another bean.
Example 9-1 Injecting a Bean into Another Bean
This example annotates an instance class field to inject an instance of the bean class Greeting
into the class Printer
.
import javax.inject.Inject; ... public class Printer { @Inject Greeting greeting; ... }
Defining the Scope of a Bean
The scope of a bean defines the duration of a user's interaction with an application that uses the bean. To enable a Web application to use a bean that injects another bean class, the bean must be able to hold state over the duration of the user's interaction with the application.
To define the scope of a bean, annotate the class declaration of the bean with the scope. The javax.enterprise.context
package defines the following scopes:
-
@RequestScoped
-
@SessionScoped
-
@ApplicationScoped
-
@ConversationScoped
-
@Dependent
For information about these scopes, see Using Scopes in The Java EE 8 Tutorial.
If you do not define the scope of a bean, the scope of the bean is @Dependent
by default. The @Dependent
scope specifies that the bean's life cycle is the life cycle of the object into which the bean is injected.
The predefined scopes except @Dependent
are contextual scopes. CDI places beans of contextual scope in the context whose life cycle is defined by the Jakarta EE specifications. For example, a session context and its beans exist during the lifetime of an HTTP session. Injected references to the beans are contextually aware. The references always apply to the bean that is associated with the context for the thread that is making the reference. The CDI container ensures that the objects are created and injected at the correct time as determined by the scope that is specified for these objects.
Example 9-2 shows how to define the scope of a bean.
Example 9-2 Defining the Scope of a Bean
This example defines the scope of the Accountant
bean class to be @RequestScoped
.
The Accountant
class in this example is qualified by the @BeanCounter
qualifier. For more information, see Using Qualifiers.
package com.example.managers; import javax.enterprise.context.RequestScoped; @RequestScoped @BeanCounter public class Accountant implements Manager { ... }
Overriding the Scope of a Bean at the Point of Injection
Overriding the scope of a bean at the point of injection enables an application to request a new instance of the bean with the default scope @Dependent
. The @Dependent
scope specifies that the bean's life cycle is the life cycle of the object into which the bean is injected.
The CDI container provides no other life cycle management for the instance. For more information about scopes, see Defining the Scope of a Bean.
Note:
The effects of overriding the scope of a bean may be unpredictable and undesirable, particularly if the overridden scope is @Request
or @Session
.
To override the scope of a bean at the point of injection, inject the bean by using the javax.enterprise.inject.New
annotation instead of the @Inject
annotation. For more information about the @Inject
annotation, see Injecting a Bean.
Using Qualifiers
Qualifiers enable you to provide more than one implementation of a particular bean type.
When you use qualifiers, you select between implementations at development time. See Using Qualifiers in The Java EE 8 Tutorial.
Note:
To select between alternative implementations at deployment time, use alternatives as explained in Providing Alternative Implementations of a Bean Type.
Using qualifiers involves the tasks that are explained in the following sections:
Defining Qualifiers for Implementations of a Bean Type
A qualifier is an application-defined annotation that enables you to identify an implementation of a bean type. Define a qualifier for each implementation of a bean type that you are providing.
Define qualifiers only if you are providing multiple implementations of a bean type and if you are not using alternatives. If no qualifiers are defend for a bean type, CDI applies the predefined qualifier @Default
when a bean of the type is injected.
Note:
CDI does not require a qualifier to be unique to a particular bean. You can define a qualifier to use for more than one bean type.
To define a qualifier:
The following examples show how to define qualifiers @BeanCounter
and @PeopleManager
for different implementations of the same bean type.
Example 9-3 Defining the @BeanCounter Qualifier
This example defines the @BeanCounter
qualifier.
package com.example.managers; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; @Qualifier @Retention(RUNTIME) @Target({METHOD, FIELD, PARAMETER, TYPE}) public @interface BeanCounter {}
Example 9-4 Defining the @PeopleManager Qualifier
This example defines the @PeopleManager
qualifier.
package com.example.managers; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; @Qualifier @Retention(RUNTIME) @Target({METHOD, FIELD, PARAMETER, TYPE}) public @interface PeopleManager {}
Parent topic: Using Qualifiers
Applying Qualifiers to a Bean
Applying qualifiers to a bean identifies the implementation of the bean type. You can apply any number of qualifiers or no qualifiers to a bean. If you do not apply any qualifiers to a bean, CDI implicitly applies the predefined qualifier @Default
to the bean.
Note:
CDI does not require a qualifier to be unique to a particular bean. You can apply the same qualifier to different types of beans in the set of beans that are available in the application.
To apply qualifiers to a bean, annotate the class declaration of the bean with each qualifier to apply. Any qualifier that you apply to a bean must be defined as explained in Defining Qualifiers for Implementations of a Bean Type.
The following examples show how to apply the qualifiers @BeanCounter
and @PeopleManager
to different implementations of the Manager
bean type.
Example 9-5 Applying the @BeanCounter Qualifier to a Bean
This example applies the @BeanCounter
qualifier to the Accountant
class. The Accountant
class is an implementation of the Manager
bean type. The @BeanCounter
qualifier is defined in Example 9-3.
package com.example.managers; ... @BeanCounter public class Accountant implements Manager {...}
Example 9-6 Applying the@ PeopleManager Qualifier to a Bean
This example applies the @PeopleManager
qualifier to the Boss
class. The Boss
class is an implementation of the Manager
bean type. The @PeopleManager
qualifier is defined in Example 9-4.
package com.example.managers; ... @PeopleManager public class Boss implements Manager {...}
Parent topic: Using Qualifiers
Injecting a Qualified Bean
To inject a qualified bean, create an injection point and annotate the injection point with the bean's qualifiers. The qualifiers at the injection point define the overall requirements of the injection target. The CDI application must contain a CDI managed bean that matches the type of the injection point and the qualifiers with which the injection point is annotated. Otherwise, a deployment error occurs. For more information about how to create an injection point, see Injecting a Bean.
If you do not annotate the injection point, the predefined qualifier @Default
is applied to the injection point by default.
CDI resolves the injection point by first matching the bean type and then matching implementations of that type with the qualifiers in the injection point.
Only one active bean class may match the bean type and qualifiers in the injection point. Otherwise, an error occurs.
A bean class is active in one of the following situations:
-
The bean class is an alternative that is enabled.
-
The bean class is not an alternative and no alternatives for its bean type are enabled.
For information about alternatives, see Providing Alternative Implementations of a Bean Type.
Example 9-7 shows how to inject a qualified bean.
Example 9-7 Injecting a Qualified Bean
This example injects the @BeanCounter
implementation of the Manager
bean type. The Manager
bean type is implemented by the following classes:
-
Accountant
, which is shown in Example 9-5 -
Boss
, which is shown in Example 9-6
In this example, the Accountant
class is injected because the bean type and qualifier of this class match the bean type and qualifier in the injection point.
package com.example.managers; ... import javax.inject.Inject; ... public class PennyPincher { @Inject @BeanCounter Manager accountant; ... }
Parent topic: Using Qualifiers
Providing Alternative Implementations of a Bean Type
The environments for the development, testing, and production deployment of an enterprise application may be very different. Differences in configuration, resource availability, and performance requirements may cause bean classes that are appropriate to one environment to be unsuitable in another environment. By providing alternative implementations of a bean type, you can modify an application at deployment time to meet such differing requirements.
Different deployment scenarios may also require different business logic in the same application. For example, country-specific sales tax laws may require country-specific sales tax business logic in an order-processing application.
CDI enables you to select from any number of alternative bean type implementations for injection instead of a corresponding primary implementation. See Using Alternatives in CDI Applications in The Java EE 8 Tutorial.
Note:
To select between alternative implementations at development time, use qualifiers as explained in Using Qualifiers.
Providing alternative implementations of a bean type involves the tasks that are explained in the following sections:
Defining an Alternative Implementation of a Bean Type
To define an alternative implementation of a bean type:
The following examples show the declaration of the primary implementation and an alternative implementation of a bean type. The alternative implementation is a mock implementation that is intended for use in testing.
Example 9-8 Declaring a Primary Implementation of a Bean Type
This example declares the primary implementation OrderImpl
of the bean type Order
.
package com.example.orderprocessor; ... public class OrderImpl implements Order { ... }
Example 9-9 Declaring an Alternative Implementation of a Bean Type
This example declares the alternative implementation MockOrderImpl
of the bean type Order
. The declaration of the primary implementation of this bean type is shown in Example 9-8.
package com.example.orderprocessor; ... import javax.enterprise.inject.Alternative; @Alternative public class MockOrderImpl implements Order { ... }
Parent topic: Providing Alternative Implementations of a Bean Type
Selecting an Alternative Implementation of a Bean Type for an Application
By default, CDI selects the primary implementation of a bean type for injection into an application. If you require an alternative implementation to be injected, you must select the alternative explicitly.
To select an alternative implementation for an application:
- Add a
class
element for the alternative to thealternatives
element in thebeans.xml
file. - In the
class
element, provide the fully qualified class name of the alternative.
For more information about the beans.xml
file, see Configuring a CDI Application.
Example 9-16 shows a class
element in the beans.xml
file for selecting an alternative implementation of a bean type.
Example 9-10 Selecting an Alternative Implementation of a Bean Type
This example selects the alternative implementation com.example.orderprocessor.MockOrderImpl
.
... <alternatives> <class>com.example.orderprocessor.MockOrderImpl</class> </alternatives> ...
Parent topic: Providing Alternative Implementations of a Bean Type
Applying a Scope and Qualifiers to a Session Bean
CDI enables you to apply a scope and qualifiers to a session bean.
A session bean is an EJB component that meets either of the following requirements:
-
The class that implements the bean is annotated with one of the following annotations:
-
javax.ejb.Singleton
, which denotes a singleton session bean -
javax.ejb.Stateful
, which denotes a stateful session bean -
javax.ejb.Stateless
, which denotes a stateless session bean
-
-
The bean is listed in the
ejb-jar.xml
deployment-descriptor file.
For more information about session beans, see the following documents:
See the following sections:
Applying a Scope to a Session Bean
The scopes that CDI allows you to apply to a session bean depend on the type of the session bean as shown in Table 9-1.
Table 9-1 Allowed CDI Scopes for Session Beans
Session Bean Type | Allowed Scopes |
---|---|
Singleton |
Either of the following scopes:
|
Stateful |
Any |
Stateless |
Dependent |
For more information about scopes in CDI, see Defining the Scope of a Bean.
When CDI injects a reference to a stateful session bean, CDI creates the bean, injects the bean's fields, and manages the stateful session bean according to its scope. When the context is destroyed, CDI calls the stateful session bean's remove method to remove the bean.
Parent topic: Applying a Scope and Qualifiers to a Session Bean
Applying Qualifiers to a Session Bean
CDI allows you to apply any qualifier to a session bean. CDI does not restrict the type of qualifier that you can apply to a session bean. For more information about qualifiers in CDI, see Using Qualifiers.
Parent topic: Applying a Scope and Qualifiers to a Session Bean
Using Producer Methods, Disposer Methods, and Producer Fields
A producer method is a method that generates an object that can then be injected. A disposer method enables an application to perform customized cleanup of an object that a producer method returns. A producer field is a field of a bean that generates an object.
A producer field is a simpler alternative to a producer method.
See Using Producer Methods, Producer Fields, and Disposer Methods in CDI Applications in The Java EE 8 Tutorial.
Defining a Producer Method
A producer method enables an application to customize how CDI managed beans are created. This customization involves overriding the process that CDI normally uses to resolve beans. A producer method enables you to inject an object that is not an instance of a CDI bean class.
A producer method must be a method of a CDI bean class or session bean class. However, a producer method may return objects that are not instances of CDI bean classes. In this situation, the producer method must return an object that matches a bean type.
A producer method can have any number of parameters. If necessary, you can apply qualifiers to these parameters. All parameters of a producer method are injection points. Therefore, the parameters of a producer method do not require the @Inject
annotation.
To define a producer method, annotate the declaration of the method with the javax.enterprise.inject.Produces
annotation.
If the producer method sometimes returns null, set the scope of the method to dependent.
Note:
Calling a producer method directly in application code does not invoke CDI.
For an example of the definition of a producer method, see Example 9-11.
Defining a Disposer Method
If you require customized cleanup of an object that a producer method returns, define a disposer method in the class that declares the producer method.
To define a disposer method, annotate the disposed parameter in the declaration of the method with the javax.enterprise.inject.Disposes
annotation. The type of the disposed parameter must be the same as the return type of the producer method.
A disposer method matches a producer method when the disposed object's injection point matches both the type and qualifiers of the producer method. You can define one disposer method to match to several producer methods in the class.
Example 9-11 shows how to use the @Produces
annotation to define a producer method and the @Disposes
annotation to define a disposer method.
Example 9-11 Defining a Producer Method and Disposer Method
This example defines the producer method connect
and the disposer method close
.
The producer method connect
returns an object of type Connection
. In the disposer method close
, the parameter connection
is the disposed parameter. This parameter is of type Connection
to match the return type of the producer method.
At run time, the CDI framework creates an instance of SomeClass
and then calls the producer method. Therefore, the CDI framework is responsible for injecting the parameters that are passed to the producer method.
The scope of the producer method is @RequestScoped
. When the request context is destroyed, if the Connection
object is in the request context, CDI calls the disposer method for this object. In the call to the disposer method, CDI passes the Connection
object as a parameter.
import javax.enterprise.inject.Produces; import javax.enterprise.inject.Disposes; import javax.enterprise.context.RequestScoped; public class SomeClass { @Produces @RequestScoped public Connection connect(User user) { return createConnection(user.getId(), user.getPassword()); } private Connection createConnection( String id, String password) {...} public void close(@Disposes Connection connection) { connection.close(); } }
Defining a Producer Field
A producer field is a simpler alternative to a producer method. A producer field must be a field of a managed bean class or session bean class. A producer field may be either static or nonstatic, subject to the following constraints:
-
In a session bean class, the producer field must be a static field.
-
In a managed bean class, the producer field can be either static or nonstatic.
To define a producer field, annotate the declaration of the field with the javax.enterprise.inject.Produces
annotation.
If the producer field may contain a null when accessed, set the scope of the field to dependent.
Note:
Using a producer field directly in application code does not invoke CDI.
Producer fields do not have disposers.
Initializing and Preparing for the Destruction of a Managed Bean
CDI managed bean classes and their superclasses support the annotations for initializing and preparing for the destruction of a managed bean.
These annotations are defined in JSR 250: Common Annotations for the Java Platform. For more information, see Using Jakarta EE Annotations and Dependency Injection.
Initializing a Managed Bean
Initializing a managed bean specifies the life cycle callback method that the CDI framework should call after dependency injection but before the class is put into service.
To initialize a managed bean:
Intercepting Method Invocations and Life Cycle Events of Bean Classes
Intercepting a method invocation or a life cycle event of a bean class interposes an interceptor class in the invocation or event. When an interceptor class is interposed, additional actions that are defined in the interceptor class are performed.
An interceptor class simplifies the maintenance of code for tasks that are frequently performed and are separate from the business logic of the application. Examples of such tasks are logging and auditing.
Note:
The programming model for interceptor classes is optimized for operations that are separate from the business logic of the application. To intercept methods that perform operations with business semantics, use a decorator class as explained in Decorating a Managed Bean Class.
The interceptors that were introduced in the Java EE 5 specification are specific to EJB components. For more information about Java EE 5 interceptors, see Specifying Interceptors for Business Methods or Life Cycle Callback Events in Developing Enterprise JavaBeans for Oracle WebLogic Server.
CDI enables you to use interceptors with the following types of Jakarta EE managed objects:
-
CDI managed beans
-
EJB session beans
-
EJB message-driven beans
Note:
You cannot use interceptors with EJB entity beans because CDI does not support EJB entity beans.
See Using Interceptors in CDI Applications in The Java EE 8 Tutorial.
Intercepting method invocations and life cycle events of bean classes involves the tasks that are explained in the following sections:
Defining an Interceptor Binding Type
An interceptor binding type is an application-defined annotation that associates an interceptor class with an intercepted bean. Define an interceptor binding type for each type of interceptor that you require.
Note:
CDI does not require an interceptor binding type to be unique to a particular interceptor class. You can define an interceptor binding type to use for more than one interceptor class.
To define an interceptor binding type:
Example 9-12 Defining An Interceptor Binding Type
This example defines the @Transactional
interceptor binding type.
package com.example.billpayment.interceptor; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.interceptor.InterceptorBinding; @InterceptorBinding @Target({METHOD, TYPE}) @Retention(RUNTIME) public @interface Transactional {}
Defining an Interceptor Class
An interceptor class is used to interpose in method invocations or life cycle events that occur in an associated target bean class. In an interceptor class, provide the code for tasks that are frequently performed and are separate from the business logic of the application, such as logging and auditing.
To define an interceptor class:
Example 9-13 shows how to define an interceptor class.
Example 9-13 Defining an Interceptor Class
This example defines the interceptor class for which the @Transactional
interceptor binding type is defined. The manageTransaction
method of this class is an interceptor method. The @Transactional
interceptor binding is defined in Example 9-12.
package com.example.billpayment.interceptor; import javax.annotation.Resource; import javax.interceptor.*; ... @Transactional @Interceptor public class TransactionInterceptor { @Resource UserTransaction transaction; @AroundInvoke public Object manageTransaction(InvocationContext ctx) throws Exception { ... } }
Identifying Methods for Interception
Identifying methods for interception associates the methods with the interceptor that is invoked when the methods are invoked. CDI enables you to identify all methods of a bean class or only individual methods of a bean class for interception.
-
To identify all methods of a bean class for interception, annotate the declaration of the bean class with the appropriate interceptor binding type.
-
To identify an individual method of a bean class for interception, annotate the declaration of the method with the appropriate interceptor binding type.
CDI does not require the signature of an intercepted method to match the signature of the interceptor method. To determine the arguments and return type of an intercepted method, an interceptor must query an interceptor context. Therefore, you can intercept any method or life cycle event in a bean class without any knowledge at compilation time of the interfaces of bean class.
Note:
An implementation of a Java EE 5 interceptor must be declared in the annotation on the method that is to be intercepted. A CDI interceptor uses an interceptor binding to identify an interceptor method and to relate an intercepted method to its interceptor method. Both the intercepted method and the interceptor method must be annotated with the binding. In this way, the intercepted method and the interceptor are related to each other only through the interceptor binding.
Example 9-14 Identifying All Methods of a Bean Class for Interception
This example identifies all methods of the ShoppingCart
class for interception by the @Transactional
interceptor.
package com.example.billpayment.interceptor; @Transactional public class ShoppingCart { ... }
Example 9-15 Identifying an Individual Method of a Class for Interception
This example identifies only the checkout
method of the ShoppingCart
class for interception by the @Transactional
interceptor.
package com.example.billpayment.interceptor; public class ShoppingCart { ... @Transactional public void checkout() { ... } }
Enabling an Interceptor
By default, an interceptor is disabled. If you require an interceptor to be interposed in method invocations and events, you must enable the interceptor explicitly.
To enable an interceptor:
For more information about the beans.xml
file, see Configuring a CDI Application.
Example 9-16 shows a class
element in the beans.xml
file for enabling an interceptor class.
Example 9-16 Enabling an Interceptor Class
This example enables the interceptor class com.example.billpayment.interceptor.TransactionInterceptor
. The interceptor class is defined in Example 9-13.
... <interceptors> <class>com.example.billpayment.interceptor.TransactionInterceptor</class> </interceptors> ...
Applying an Interceptor on a Producer
In CDI 1.x, the interceptor is not bound to a producer bean. CDI 2.0 introduces the interface javax.enterprise.inject.spi.InterceptionFactory<T>
, which allows to apply interceptors programmatically to the return value of a producer method.
The InterceptionFactory
interface allows to create a wrapper instance whose method invocations are intercepted by method interceptors and forwarded to a provided instance.
publicinterfaceInterceptionFactory<T> {
InterceptionFactory<T> ignoreFinalMethods();
AnnotatedTypeConfigurator<T> configure();
T createInterceptedInstance(T instance);
}
You can obtain an implementation of InterceptionFactory
by calling the BeanManager.createInterceptionFactory()
. The following example shows a producer method using the InterceptionFactory
:
@Produces
@RequestScoped
public Product createInterceptedProduct(InterceptionFactory<Product> interceptionFactory) {
interceptionFactory.configure().add(ActionBinding.Literal.INSTANCE);
return interceptionFactory.createInterceptedInstance(new Product());
}
See Using Interceptors in CDI Applications in Java EE 8 Tutorial for more information about using interceptors.
Decorating a Managed Bean Class
Decorating a managed bean class enables you to intercept invocations of methods in the decorated class that perform operations with business semantics.
You can decorate any managed bean class.
Note:
The programming model for decorator classes is optimized for operations that perform the business logic of the application. To intercept methods that are separate from the business logic of an application, use an interceptor class as explained in Intercepting Method Invocations and Life Cycle Events of Bean Classes.
See Using Decorators in The Java EE 8 Tutorial.
Decorating a managed bean class involves the tasks that are explained in the following sections:
Defining a Decorator Class
A decorator class intercepts invocations of methods in the decorated class that perform operations with business semantics. A decorator class and an interceptor class are similar because both classes provide an around-method interception. However, a method in a decorator class has the same signature as the intercepted method in the decorated bean class.
To define a decorator class:
-
Write a Java class that implements the same interface as the bean class that you are decorating.
If you want to intercept only some methods of the decorated class, declare the decorator class as an abstract class. If you declare the class as abstract, you are not required to implement all the methods of the bean class that you are decorating.
-
Annotate the class declaration of the decorator class with the
javax.decorator.Decorator
annotation. -
Implement the methods of the decorated bean class that you want to intercept.
If the decorator class is a concrete class, you must implement all the methods of the bean class that you are decorating.
You must ensure that the intercepting method in a decorator class has the same signature as the intercepted method in the decorated bean class.
-
Add a delegate injection point to the decorator class.
A decorator class must contain exactly one delegate injection point. A delegate injection point injects a delegate object, which is an instance of the decorated class, into the decorator object.
You can customize how any method in the decorator object handles the implementation of the decorated method. CDI allows but does not require the decorator object to invoke the corresponding delegate object. Therefore, you are free to choose whether the decorator object invokes the corresponding delegate object.
-
In the decorator class, inject an instance of the bean class that you are decorating.
-
Annotate the injection point with the
javax.decorator.Delegate
annotation. -
Apply qualifiers that you require to the injection point, if any.
If you apply qualifiers to the injection point, the decorator applies only to beans whose bean class matches the qualifiers of the injection point.
-
Note:
No special declaration, such as an annotation, is required to define a decorated bean class. An enabled decorator class applies to any bean class or session bean that matches the bean type and qualifiers of the delegate injection point.
Example 9-17 shows the definition of a decorator class.
Example 9-17 Defining a Decorator Class
This example defines the decorator class DataAccessAuthDecorator
. This class decorates any bean of type DataAccess
.
Because only some methods of the decorated class are to be intercepted, the class is declared as an abstract class. This class injects a delegate instance delegate
of the decorated implementation of the DataAcess
bean type.
import javax.decorator.*; import javax.inject.Inject; import java.lang.Override; ... @Decorator public abstract class DataAccessAuthDecorator implements DataAccess { @Inject @Delegate DataAccess delegate; @Override public void delete(Object object) { authorize(SecureAction.DELETE, object); delegate.delete(object); } private void authorize(SecureAction action, Object object) { ... } }
Parent topic: Decorating a Managed Bean Class
Enabling a Decorator Class
By default, a decorator class is disabled. If you require a decorator class to be invoked in a CDI application, you must enable the decorator class explicitly.
To enable an decorator class:
Note:
Any interceptor classes that are defined for an application are invoked before the application's decorator classes.
For more information about the beans.xml
file, see Configuring a CDI Application.
Example 9-18 shows a class
element in the beans.xml
file for enabling a decorator class.
Example 9-18 Enabling a Decorator Class
This example enables the decorator class com.example.billpayment.decorator.DataAccessAuthDecorator
.
... <decorators> <class>com.example.billpayment.decorator.DataAccessAuthDecorator</class> </decorators> ...
Parent topic: Decorating a Managed Bean Class
Assigning an EL Name to a CDI Bean Class
EL enables components in the presentation layer to communicate with managed beans that implement application logic.
Components in the presentation layer are typically Jakarta Server Faces (JSF) pages and Jakarta Server Pages (JSP) pages. See JSP Expression Language in Developing Web Applications, Servlets, and JSPs for Oracle WebLogic Server.
In the scripting languages in JSP pages and JSF pages, the syntax of an injected variable is identical to the syntax of a built-in variable of these languages. Any CDI bean that is injected into a JSP page or JSF page must be accessible through an EL name. See Giving Beans EL Names in The Java EE 8 Tutorial.
To assign an EL name to a CDI bean class, annotate the class declaration of the bean class with the javax.inject.Named
annotation.
If you do not specify a name, the EL name is the unqualified class name with the first character in lower case. For example, if the unqualified class name is ShoppingCart
, the EL name is shoppingCart
.
To specify a name, set the value
element of the @Named
annotation to the name that you require.
Note:
To assign an EL name to a CDI bean class, you must annotate the bean class declaration with the @Named
annotation. If the class is not annotated with @Named
, the CDI bean class does not have an EL name.
The following example shows how to use the @Named
annotation to assign an EL name to a CDI bean class. This example assigns the EL name cart
to the ShoppingCart
class.
import javax.enterprise.context.SessionScoped; @SessionScoped @Named("cart") public class ShoppingCart { public String getTotal() { ... } ... }
Any bean that a JSP page or JSF page accesses must conform to the JavaBeans standard. To access a CDI managed bean from a JSP page or JSF page through the bean's EL name, use a syntax that is similar to the syntax for JavaBeans components.
The following example shows how an instance of the ShoppingCart
class is accessed in a JSF page through the EL name that is assigned to the class.
Example 9-19 Accessing a Bean Through its EL Name
This example accesses an instance of the ShoppingCart
class to display the value of its total
property in a JSF page.
This property is returned by the getTotal
getter method of the ShoppingCart
class.
... <h:outputText value="#{cart.total}"/> ...
Defining and Applying Stereotypes
In a large application in which several beans perform similar functions, you may require the same set of annotations to be applied to several bean classes. Defining a stereotype requires you to define the set of annotations only once.
You can then use the stereotype to guarantee that the same set of annotations is applied to all bean classes that require the annotations. See Using Stereotypes in The Java EE 8 Tutorial.
Defining and applying stereotypes involves the tasks that are explained in the following sections:
Defining a Stereotype
A stereotype is an application-defined annotation type that incorporates other annotation types.
To define a stereotype:
The following example shows the definition of a stereotype.
Example 9-20 Defining a Stereotype
This example defines the stereotype @Action
, which specifies the following for each bean that the stereotype annotates:
-
The default scope is request scope unless the scope is overridden with a scope annotation.
-
The default EL name is assigned to the bean unless the name is overridden with the
@Named
annotation. -
The interceptor bindings
@Secure
and@Transactional
are applied to the bean. The definition of these interceptor bindings is beyond the scope of this example.
import javax.enterprise.inject.Stereotype; import javax.inject.Named; import javax.enterprise.context.RequestScoped; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; @RequestScoped @Secure @Transactional @Named @Stereotype @Target(TYPE) @Retention(RUNTIME) public @interface Action {}
Parent topic: Defining and Applying Stereotypes
Applying Stereotypes to a Bean
To apply stereotypes to a bean, annotate the class declaration of the bean with each stereotype to apply. You can apply any number of stereotypes to a bean. Any stereotype that you apply to a bean must be defined as explained in Defining a Stereotype.
Example 9-21 shows how to apply stereotypes to a bean.
Example 9-21 Applying Stereotypes to a Bean
This example applies the stereotypes @Action
and @Mock
to the bean class MockLoginAction
. The definition of the @Action
stereotype is shown in Example 9-20. The definition of the @Mock
stereotype is beyond the scope of this example.
@Action @Mock public class MockLoginAction extends LoginAction { ... }
Parent topic: Defining and Applying Stereotypes
Using Events for Communications Between Beans
Events enable beans to communicate information without any compilation-time dependency.
At run time, your application may perform operations that generate information or cause state changes that must be communicated between beans. For example, an application may require stateful beans in one architectural tier of the application to synchronize their internal state with state changes that occur in a different tier.
Events enable beans to communicate this information without any compilation-time dependency. One bean can define an event, another bean can send the event, and yet another bean can handle the event. The beans can be in separate packages and even in separate tiers of the application. See Using Events in The Java EE 8 Tutorial.
Using events for communications between beans involves the tasks that are explained in the following sections:
Defining an Event Type
An event type is a Java class that represents the information that you want to communicate between beans. For example, an event type may represent the state information that a stateful bean must synchronize with state changes in a different tier of an application.
Define an event type for each set of changes that you want to communicate between beans.
To define an event type:
Parent topic: Using Events for Communications Between Beans
Sending an Event
To communicate a change that occurs in response to an operation, your application must send an event of the correct type when performing the operation. CDI provides a predefined event dispatcher object that enables application code to send an event and select the associated qualifiers at run time.
To send an event:
Example 9-22 shows how to send an event.
Example 9-22 Sending an Event
This example injects an instance of the event of type User
with the qualifier @LoggedIn
. The fire
method sends only User
events to which the @LoggedIn
qualifier is applied.
import javax.enterprise.event.Event; import javax.enterprise.context.SessionScoped; import javax.inject.Inject; import java.io.Serializable; @SessionScoped public class Login implements Serializable { @Inject @LoggedIn Event<User> userLoggedInEvent; private User user; public void login(Credentials credentials) { //... use credentials to find user if (user != null) { userLoggedInEvent.fire(user); } } ... }
Parent topic: Using Events for Communications Between Beans
Handling an Event
Any CDI managed bean class can handle events.
To handle an event:
Example 9-23 shows how to declare an observer method for receiving qualified events of a particular type. Example 9-24 shows how to declare an observer method for receiving all events of a particular type.
Example 9-23 Handling a Qualified Event of a Particular Type
This example declares the afterLogin
method in which the parameter user
is annotated with the @Observes
annotation and the @LoggedIn
qualifier. This method is called when an event of type User
with the qualifier @LoggedIn
is sent.
import javax.enterprise.event.Observes; public void afterLogin(@Observes @LoggedIn User user) { ... }
Example 9-24 Handling Any Event of a Particular Type
This example declares the afterLogin
method in which the parameter user
is annotated with the @Observes
annotation. This method is called when any event of type User
is sent.
import javax.enterprise.event.Observes; public void afterLogin(@Observes User user) { ... }
Parent topic: Using Events for Communications Between Beans
Injecting a Predefined Bean
Predefined beans are injected with dependent scope and the predefined default qualifier @Default
.
CDI provides predefined beans that implement the following interfaces:
-
javax.transaction.UserTransaction
-
Java Transaction API (JTA) user transaction.
-
java.security.Principal
-
The abstract notion of a principal, which represents any entity, such as an individual, a corporation, and a login ID.
The principal represents the identity of the current caller. Whenever the injected principal is accessed, it always represents the identity of the current caller.
For example, a principal is injected into a field at initialization. Later, a method that uses the injected principal is called on the object into which the principal was injected. In this situation, the injected principal represents the identity of the current caller when the method is run.
-
javax.validation.Validator
-
Validator for bean instances.
The bean that implements this interface enables a
Validator
object for the default bean validationValidatorFactory
object to be injected. -
javax.validation.ValidatorFactory
-
Factory class for returning initialized
Validator
instances.The bean that implements this interface enables the default bean validation
ValidatorFactory
object to be injected.
To inject a predefined bean, create an injection point by using the javax.annotation.Resource
annotation to obtain an instance of the bean. For the bean type, specify the class name of the interface that the bean implements.
Predefined beans are injected with dependent scope and the predefined default qualifier @Default
.
For more information about injecting resources, see Resource Injection in The Java EE 8 Tutorial.
Example 9-25 shows how to use the @Resource
annotation to inject a predefined bean.
Example 9-25 Injecting a Predefined Bean
This example injects a user transaction into the servlet class TransactionServlet
. The user transaction is an instance of the predefined bean that implements the javax.transaction.UserTransaction
interface.
import javax.annotation.Resource; import javax.servlet.http.*; ... public class TransactionServlet extends HttpServlet { @Resource UserTransaction transaction; ... }
Injecting and Qualifying Resources
Java EE 5 resource injection relies on strings for configuration. Typically, these strings are JNDI names that are resolved when an object is created. CDI ensures type-safe injection of beans by selecting the bean class on the basis of the Java type that is specified in the injection point.
Even in a CDI bean class, Java EE 5 resource injection is required to access real resources such as data sources, Java Message Service (JMS) resources, and Web service references. Because CDI bean classes can use Java EE 5 resource injection, you can use producer fields to minimize the reliance on Java EE 5 resource injection. In this way, CDI simplifies how to encapsulate the configuration that is required to access the correct resource.
To minimize the reliance on Java EE 5 resource injection:
-
Use Java EE 5 resource injection in only one place in the application.
-
Use producer fields to translate the injected resource type into a CDI bean.
You can the inject this CDI bean into the application in the same way as any other CDI bean.
For more information about producer fields, see Defining a Producer Field.
import javax.annotation.Resource; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceUnit; import javax.ejb.EJB; import javax.xml.ws.WebServiceRef; ... public class SomeClass { @WebServiceRef(lookup="java:app/service/PaymentService") PaymentService paymentService; @EJB(ejbLink="../payment.jar#PaymentService") PaymentService paymentService; @Resource(lookup="java:global/env/jdbc/CustomerDatasource") Datasource customerDatabase; @PersistenceContext(unitName="CustomerDatabase") EntityManager customerDatabasePersistenceContext; @PersistenceUnit(unitName="CustomerDatabase") EntityManagerFactory customerDatabasePersistenceUnit; ... }
The following example shows how to inject the same set of resources by combining Java EE 5 resource injection with CDI producer fields.
SomeClass
class is annotated with @ApplicationScoped
to set the scope of this bean to application. The @Dependent
scope is implicitly applied to the producer fields.import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import javax.annotation.Resource; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceUnit; import javax.ejb.EJB; javax.xml.ws.WebServiceRef; ... @ApplicationScoped public class SomeClass { @Produces @WebServiceRef(lookup="java:app/service/PaymentService") PaymentService paymentService; @Produces @EJB(ejbLink="../their.jar#PaymentService") PaymentService paymentService; @Produces @CustomerDatabase @Resource(lookup="java:global/env/jdbc/CustomerDatasource") Datasource customerDatabase; @Produces @CustomerDatabase @PersistenceContext(unitName="CustomerDatabase") EntityManager customerDatabasePersistenceContext; @Produces @CustomerDatabase @PersistenceUnit(unitName="CustomerDatabase") EntityManagerFactory customerDatabasePersistenceUnit; ... }
CDI enables you to use Jakarta EE resources in CDI applications in a way that is consistent with CDI. To use Jakarta EE resources in this way, inject the resources as CDI beans into other beans.
The following example shows how to inject a Jakarta EE resource as a CDI bean into another bean.
import javax.enterprise.context.RequestScoped; import javax.enterprise.inject.Inject; @RequestScoped public class SomeOtherClass { ... @Inject @CustomerDatabase private EntityManagerFactory emf; ... }
Another class, for example YetAnotherClass
, could inject a field of type SomeOtherClass
. If an instance of SomeOtherClass
does not already exist in the current request context, CDI performs the following sequence of operations:
-
Constructing the instance of
SomeOtherClass
-
Injecting the reference to the entity manager factory by using the producer field.
-
Saving the new instance of
SomeOtherClass
in the current request context
In every case, CDI injects the reference to this instance of SomeOtherClass
into the field in YetAnotherClass
. When the request context is destroyed, the instance of SomeOtherClass
and its reference to the entity manager factory are destroyed.
Using CDI With JCA Technology
WebLogic Server supports CDI in embedded resource adapters and global resource adapters. To enable a resource adapter for CDI, provide a beans.xml
file in the META-INF
directory of the packaged archive of the resource adapter.
For more information about the beans.xml
file, see Configuring a CDI Application.
All classes in the resource adapter are available for injection. All classes in the resource adapter can be CDI managed beans except for the following classes:
-
Resource adapter beans. These beans are classes that are annotated with the
javax.resource.spi.Connector
annotation or are declared as corresponding elements in the resource adapter deployment descriptorra.xml
. -
Managed connection factory beans. These beans are classes that are annotated with the
javax.resource.spi.ConnectionDefinition
annotation or thejavax.resource.spi.ConnectionDefinitions
annotation, or are declared as corresponding elements inra.xml
. -
Activation specification beans. These beans are classes that are annotated with the
javax.resource.spi.Activation
annotation or are declared as corresponding elements inra.xml
. -
Administered object beans. These beans are classes that are annotated with the
javax.resource.spi.AdministeredObject
annotation or are declared as corresponding elements inra.xml
.
Configuring a CDI Application
Configuring a CDI application enables CDI services for the application. You must configure a CDI application to identify the application as a CDI application. No special declaration, such as an annotation, is required to define a CDI managed bean. And no module type is defined specifically for packaging CDI applications.
To configure a CDI application, provide a file that is named beans.xml
in the packaged archive of the application. The beans.xml
file must be an instance of the extensible markup language (XML) schema beans_2_0.xsd
.
If your application does not use any alternatives, interceptors, or decorators, the beans.xml
file can be empty. However, you must provide the beans.xml
file even if the file is empty.
If your CDI application uses alternatives, interceptors, or decorators, you must enable these items by declaring them in the beans.xml
file. For more information, see:
The required location of the beans.xml
file depends on the type of the application:
-
For a Web application, the
beans.xml
file must be in theWEB-INF
directory. -
For an EJB module, resource archive (RAR) file, application client JAR file, or library JAR file, the
beans.xml
file must be in theMETA-INF
directory.
You can provide CDI bean archives in the lib
directory of an EJB module. You must provide a beans.xml
file in the META-INF
directory of each CDI bean archive the lib
directory of an EJB module.
Example 9-26 shows a beans.xml
file for configuring a CDI application.
Example 9-26 beans.xml File for Configuring a CDI Application
This example configures a CDI application by enabling the following classes:
-
The alternative implementation
com.example.orderprocessor.MockOrderImpl
-
The interceptor class
com.example.billpayment.interceptor.TransactionInterceptor
-
The decorator class
com.example.billpayment.decorator.DataAccessAuthDecorator
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"> <alternatives> <class>com.example.orderprocessor.MockOrderImpl</class> </alternatives> <interceptors> <class>com.example.billpayment.interceptor.TransactionInterceptor</class> </interceptors> <decorators> <class>com.example.billpayment.decorator.DataAccessAuthDecorator</class> </decorators> </beans>
Enabling and Disabling CDI
CDI for a domain is enabled by default. However, even when an application does not use CDI, there is some CDI initialization that occurs when you deploy an application in WebLogic Server. To maximize deployment performance for applications that do not use CDI, you can disable CDI.
You can control whether CDI is enabled in the domain by setting the Policy
parameter on the CDI container. When this parameter is set to Enabled
, CDI is enabled for all applications in the domain. When the Policy
parameter is set to Disabled
, CDI is disabled for all applications in the domain.
You can disable CDI only for a domain.
Enabling and Disabling CDI for a Domain
To disable CDI for every application that is deployed to a domain, add the following lines to the config.xml
file:
<domain>
<cdi-container>
<policy>Disabled</policy>
</cdi-container>
<domain>
You can use the WLST scripting tool to enable or disable CDI for a domain. The following examples demonstrate how to use WLST to enable and disable CDI for a domain whether you are online or offline.
Example 9-27 Enabling CDI While Online
In the following example, WebLogic Server is running. The arguments username and password represent the credentials for the user who is connecting WLST to the server, and url represents the listen address and listen port of the server instance (for example, localhost:7001). Also note that domain represents the domain name.
connect('user','password','url')
domainConfig()
edit()
cd('CdiContainer/mydomain')
startEdit()
set('Policy','Enabled') // 'Enabled' or 'Disabled'
validate()
save()
activate(block="true")
Example 9-28 Enabling CDI While Offline
In the following example, domain represents the path of your domain (for example, /oracle/wls/
mydomain). Also note that mydomain
must match the domain name.
readDomain('domain')
create('mydomain','CdiContainer')
cd('CdiContainer/mydomain')
set('Policy','Enabled') // 'Enabled' or 'Disabled'
updateDomain()
closeDomain()
Parent topic: Enabling and Disabling CDI
Implicit Bean Discovery
CDI 1.1 and Java EE 7 introduced the concept of implicit bean archives. An implicit bean archive is an archive of a JAR or a WAR file that does not contain a beans.xml
file; it contains beans that can be managed by CDI.
This can significantly increase the time that it takes to deploy an application. This increase in time is especially noticeable when applications built for releases prior to Java EE 7 are deployed on a Java EE 7 application server. To be compatible with CDI 1.0, WebLogic Server contains an option that sets the container to ignore the archive even when the beans.xml
file is not present.
You control whether implicit bean discovery is enabled in the domain by setting the implicit-bean-discovery-enabled
parameter on the CDI container. When this parameter is set to 1
, implicit bean discovery is enabled for all applications in the domain. When the implicit-bean-discovery-enabled
parameter is set to 0
, implicit bean discovery is disabled for all applications in the domain.
You can disable implicit bean discovery only for a domain.
Enabling and Disabling Implicit Bean Discovery for a Domain
To disable implicit bean discovery for every application that is deployed to a domain, add the following lines config.xml
file:
<domain>
<cdi-container>
<implicit-bean-discovery-enabled>false</implicit-bean-discobery-enabled>
</cdi-container>
<domain>
You can use WLST scripting too to enable or disable this feature. The following examples demonstrate how to use WLST to enable and disable implicit bean discovery for a domain whether you are online or offline.
Example 9-29 Enabling Implicit Bean Discovery Using WLST Online
In the following example, WebLogic Server is running. The arguments username and password represent the credentials for the user who is connecting WLST to the server, and url represents the listen address and listen port of the server instance (for example, localhost:7001). Also note that domain represents the domain name.
connect('user','password','url') domainConfig() edit() cd('CdiContainer/mydomain') startEdit() set('ImplicitBeanDiscoveryEnabled',1) // 1 to enable 0 to disable validate() save() activate(block="true")
Example 9-30 Enabling Implicit Bean Discovery Using WLST Offline
In the following example, domain represents the path of your domain (for example, /oracle/wls/
mydomain). Also note that mydomain
must match the domain name.
readDomain(domain)
create('mydomain','CdiContainer')
cd('CdiContainer/mydomain')
set('ImplicitBeanDiscoveryEnabled',1)
// 1 to enable 0 to disable
updateDomain()
closeDomain()
Parent topic: Implicit Bean Discovery
Supporting Third-Party Portable Extensions
CDI is intended to be a foundation for frameworks, extensions, and integration with other technologies.
CDI exposes SPIs that enable the development of portable extensions to CDI, such as:
-
Integration with business process management engines
-
Integration with third-party frameworks such as Spring, Seam, GWT or Wicket
-
New technology that is based upon the CDI programming model
The SPIs that enable the development of portable extensions to CDI are provided in the javax.enterprise.inject.spi
package.
Code in CDI extensions can handle events that are sent by the CDI framework.
For more information, see "Portable extensions" in JSR 365: Contexts and Dependency Injection for the Java EE platform.
Using the Built-in Annotation Literals
CDI 2.0 introduces new built-in annotation literals that can be used for creating instances of annotations.
Syntax
The following are the new built-in annotations that define a Literal
static nested class:
Table 9-2 Built-in Annotation Literals
Classes | Package |
---|---|
Any |
javax.enterprise.inject |
Default |
javax.enterprise.inject |
New |
javax.enterprise.inject |
Specialized |
javax.enterprise.inject |
Veteod |
javax.enterprise.inject |
Alternative |
javax.enterprise.inject |
Typed |
javax.enterprise.inject |
Nonbinding |
javax.enterprise.util |
Initialized |
javax.enterprise.context |
Destroyed |
javax.enterprise.context |
RequestScoped |
javax.enterprise.context |
SessionScoped |
javax.enterprise.context |
ApplicationScoped |
javax.enterprise.context |
Dependent |
javax.enterprise.context |
ConversationScoped |
javax.enterprise.context |
Example 9-31 Built-in Annotation Literals
Default defaultLiteral = new Default.Literal();
Using the Configurator Interfaces
CDI 2.0 introduced some new configurator interfaces which can be used for dynamically defining or modifying CDI objects.
The newly introduced configurator interfaces are:
AnnotatedTyeConfigurator
InjectionPointConfigurator
BeanAttributesConfigurator
BeanConfigurator
ObserverMethodConfigurator
ProducerConfigurator
See Using the Configurators Interfaces in Java EE 8 Tutorial for more information.
Bootstrapping a CDI Container
CDI 2.0 provides the standard API for bootstrapping a CDI container in Java SE. You must explicitly bootstrap the CDI container using the SeContainerInitializer
abstract class and its static method newInstance()
.
You can configure the CDI container using the API javax.enterprise.inject.se.SeContainerInitializer
before it is bootstrapped and the SeContainerInitializer.initialize()
method bootstraps the container and returns a SeContainer
instance.
See Configuring the CDI Container in Java EE 8 Tutorial for more information.