此内容没有您所选择的语言版本。
11.2. Use CDI
11.2.1. First Steps 复制链接链接已复制到粘贴板!
11.2.1.1. Enable CDI 复制链接链接已复制到粘贴板!
Contexts and Dependency Injection (CDI) is one of the core technologies in JBoss EAP 6, and is enabled by default. If for some reason it is disabled and you need to enable it, follow this procedure.
Procedure 11.1. Enable CDI in JBoss EAP 6
Check to see if the CDI subsystem details are commented out of the configuration file.
A subsystem can be disabled by commenting out the relevant section of thedomain.xmlorstandalone.xmlconfiguration files, or by removing the relevant section altogether.To find the CDI subsystem inEAP_HOME/domain/configuration/domain.xmlorEAP_HOME/standalone/configuration/standalone.xml, search them for the following string. If it exists, it is located inside the <extensions> section.<extension module="org.jboss.as.weld"/>
<extension module="org.jboss.as.weld"/>Copy to Clipboard Copied! Toggle word wrap Toggle overflow The following line must also be present in the profile you are using. Profiles are in individual <profile> elements within the <profiles> section.<subsystem xmlns="urn:jboss:domain:weld:1.0"/>
<subsystem xmlns="urn:jboss:domain:weld:1.0"/>Copy to Clipboard Copied! Toggle word wrap Toggle overflow Before editing any files, stop JBoss EAP 6.
JBoss EAP 6 modifies the configuration files during the time it is running, so you must stop the server before you edit the configuration files directly.Edit the configuration file to restore the CDI subsystem.
If the CDI subsystem was commented out, remove the comments.If it was removed entirely, restore it by adding this line to the file in a new line directly above the </extensions> tag:<extension module="org.jboss.as.weld"/>
<extension module="org.jboss.as.weld"/>Copy to Clipboard Copied! Toggle word wrap Toggle overflow - You also need to add the following line to the relevant profile in the <profiles> section.
<subsystem xmlns="urn:jboss:domain:weld:1.0"/>
<subsystem xmlns="urn:jboss:domain:weld:1.0"/>Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart JBoss EAP 6.
Start JBoss EAP 6 with your updated configuration.
JBoss EAP 6 starts with the CDI subsystem enabled.
11.2.2. Use CDI to Develop an Application 复制链接链接已复制到粘贴板!
11.2.2.1. Use CDI to Develop an Application 复制链接链接已复制到粘贴板!
Contexts and Dependency Injection (CDI) gives you tremendous flexibility in developing applications, reusing code, adapting your code at deployment or run-time, and unit testing. JBoss EAP 6 includes Weld, the reference implementation of CDI. These tasks show you how to use CDI in your enterprise applications.
11.2.2.2. Use CDI with Existing Code 复制链接链接已复制到粘贴板!
beans.xml in the META-INF/ or WEB-INF/ directory of your archive. The file can be empty.
Procedure 11.2. Use legacy beans in CDI applications
Package your beans into an archive.
Package your beans into a JAR or WAR archive.Include a
beans.xmlfile in your archive.Place abeans.xmlfile into your JAR archive'sMETA-INF/or your WAR archive'sWEB-INF/directory. The file can be empty.
You can use these beans with CDI. The container can create and destroy instances of your beans and associate them with a designated context, inject them into other beans, use them in EL expressions, specialize them with qualifier annotations, and add interceptors and decorators to them, without any modifications to your existing code. In some circumstances, you may need to add some annotations.
11.2.2.3. Exclude Beans From the Scanning Process 复制链接链接已复制到粘贴板!
One of the features of Weld, the JBoss EAP 6 implementation of CDI, is the ability to exclude classes in your archive from scanning, having container lifecycle events fired, and being deployed as beans. This is not part of the JSR-299 specification.
Example 11.1. Exclude packages from your bean
- The first one excludes all Swing classes.
- The second excludes Google Web Toolkit classes if Google Web Toolkit is not installed.
- The third excludes classes which end in the string
Blether(using a regular expression), if the system property verbosity is set tolow. - The fourth excludes Java Server Faces (JSF) classes if Wicket classes are present and the viewlayer system property is not set.
11.2.2.4. Use an Injection to Extend an Implementation 复制链接链接已复制到粘贴板!
You can use an injection to add or change a feature of your existing code. This example shows you how to add a translation ability to an existing class. The translation is a hypothetical feature and the way it is implemented in the example is pseudo-code, and only provided for illustration.
buildPhrase. The buildPhrase method takes as an argument the name of a city, and outputs a phrase like "Welcome to Boston." Your goal is to create a version of the Welcome class which can translate the greeting into a different language.
Example 11.2. Inject a Translator Bean Into the Welcome Class
Translator object into the Welcome class. The Translator object may be an EJB stateless bean or another type of bean, which can translate sentences from one language to another. In this instance, the Translator is used to translate the entire greeting, without actually modifying the original Welcome class at all. The Translator is injected before the buildPhrase method is implemented.
11.2.3. Ambiguous or Unsatisfied Dependencies 复制链接链接已复制到粘贴板!
11.2.3.1. About Ambiguous or Unsatisfied Dependencies 复制链接链接已复制到粘贴板!
- It resolves the qualifier annotations on all beans that implement the bean type of an injection point.
- It filters out disabled beans. Disabled beans are @Alternative beans which are not explicitly enabled.
11.2.3.2. About Qualifiers 复制链接链接已复制到粘贴板!
Example 11.3. Define the @Synchronous and @Asynchronous Qualifiers
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Synchronous {}
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Synchronous {}
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Asynchronous {}
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Asynchronous {}
Example 11.4. Use the @Synchronous and @Asynchronous Qualifiers
This task shows an ambiguous injection and removes the ambiguity with a qualifier. Read more about ambiguous injections at Section 11.2.3.1, “About Ambiguous or Unsatisfied Dependencies”.
Example 11.5. Ambiguous injection
Welcome, one which translates and one which does not. In that situation, the injection below is ambiguous and needs to be specified to use the translating Welcome.
Procedure 11.3. Resolve an Ambiguous Injection with a Qualifier
Create a qualifier annotation called
@Translating.@Qualifier @Retention(RUNTIME) @Target({TYPE,METHOD,FIELD,PARAMETERS}) public @interface Translating{}@Qualifier @Retention(RUNTIME) @Target({TYPE,METHOD,FIELD,PARAMETERS}) public @interface Translating{}Copy to Clipboard Copied! Toggle word wrap Toggle overflow Annotate your translating
Welcomewith the@Translatingannotation.Copy to Clipboard Copied! Toggle word wrap Toggle overflow Request the translating
Welcomein your injection.You must request a qualified implementation explicitly, similar to the factory method pattern. The ambiguity is resolved at the injection point.Copy to Clipboard Copied! Toggle word wrap Toggle overflow
The TranslatingWelcome is used, and there is no ambiguity.
11.2.4. Managed Beans 复制链接链接已复制到粘贴板!
11.2.4.1. About Managed Beans 复制链接链接已复制到粘贴板!
bean.
@Inject) is a bean. This includes every JavaBean and every EJB session bean. The only requirement to enable the mentioned services in beans is that they reside in an archive (a JAR, or a Java EE module such as a WAR or EJB JAR) that contains a special marker file: META-INF/beans.xml.
11.2.4.2. Types of Classes That are Beans 复制链接链接已复制到粘贴板!
@ManagedBean, but in CDI you do not need to. According to the specification, the CDI container treats any class that satisfies the following conditions as a managed bean:
- It is not a non-static inner class.
- It is a concrete class, or is annotated
@Decorator. - It is not annotated with an EJB component-defining annotation or declared as an EJB bean class in
ejb-jar.xml. - It does not implement interface
javax.enterprise.inject.spi.Extension. - It has either a constructor with no parameters, or a constructor annotated with
@Inject.
11.2.4.3. Use CDI to Inject an Object Into a Bean 复制链接链接已复制到粘贴板!
META-INF/beans.xml or WEB-INF/beans.xml file, each object in your deployment can be injected using CDI.
Inject an object into any part of a bean with the
@Injectannotation.To obtain an instance of a class, within your bean, annotate the field with@Inject.Example 11.6. Injecting a
TextTranslatorinstance into aTranslateControllerpublic class TranslateController { @Inject TextTranslator textTranslator; ...public class TranslateController { @Inject TextTranslator textTranslator; ...Copy to Clipboard Copied! Toggle word wrap Toggle overflow Use your injected object's methods
You can use your injected object's methods directly. Assume thatTextTranslatorhas a methodtranslate.Example 11.7. Use your injected object's methods
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Use injection in the constructor of a bean
You can inject objects into the constructor of a bean, as an alternative to using a factory or service locator to create them.Example 11.8. Using injection in the constructor of a bean
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Use the
Instance(<T>)interface to get instances programmatically.TheInstanceinterface can return an instance of TextTranslator when parameterized with the bean type.Example 11.9. Obtaining an instance programmatically
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
When you inject an object into a bean all of the object's methods and properties are available to your bean. If you inject into your bean's constructor, instances of the injected objects are created when your bean's constructor is called, unless the injection refers to an instance which already exists. For instance, a new instance would not be created if you inject a session-scoped bean during the lifetime of the session.
11.2.5. Contexts, Scopes, and Dependencies 复制链接链接已复制到粘贴板!
11.2.5.1. Contexts and Scopes 复制链接链接已复制到粘贴板!
@RequestScoped, @SessionScoped, and @ConversationScope.
11.2.5.2. Available Contexts 复制链接链接已复制到粘贴板!
| Context | Description |
|---|---|
| @Dependent | The bean is bound to the lifecycle of the bean holding the reference. |
| @ApplicationScoped | Bound to the lifecycle of the application. |
| @RequestScoped | Bound to the lifecycle of the request. |
| @SessionScoped | Bound to the lifecycle of the session. |
| @ConversationScoped | Bound to the lifecycle of the conversation. The conversation scope is between the lengths of the request and the session, and is controlled by the application. |
| Custom scopes | If the above contexts do not meet your needs, you can define custom scopes. |
11.2.6. Bean Lifecycle 复制链接链接已复制到粘贴板!
11.2.6.1. Manage the Lifecycle of a Bean 复制链接链接已复制到粘贴板!
This task shows you how to save a bean for the life of a request. Several other scopes exist, and you can define your own scopes.
@Dependent. This means that the bean's lifecycle is dependent upon the lifecycle of the bean which holds the reference. For more information, see Section 11.2.5.1, “Contexts and Scopes”.
Procedure 11.4. Manage Bean Lifecycles
Annotate the bean with the scope corresponding to your desired scope.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow When your bean is used in the JSF view, it holds state.
<h:form> <h:inputText value="#{greeter.city}"/> <h:commandButton value="Welcome visitors" action="#{greeter.welcomeVisitors}"/> </h:form><h:form> <h:inputText value="#{greeter.city}"/> <h:commandButton value="Welcome visitors" action="#{greeter.welcomeVisitors}"/> </h:form>Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Your bean is saved in the context relating to the scope that you specify, and lasts as long as the scope applies.
11.2.6.2. Use a Producer Method 复制链接链接已复制到粘贴板!
This task shows how to use producer methods to produce a variety of different objects which are not beans for injection.
Example 11.10. Use a producer method instead of an alternative, to allow polymorphism after deployment
@Preferred annotation in the example is a qualifier annotation. For more information about qualifiers, refer to: Section 11.2.3.2, “About Qualifiers”.
@Inject @Preferred PaymentStrategy paymentStrategy;
@Inject @Preferred PaymentStrategy paymentStrategy;
Example 11.11. Assign a scope to a producer method
@Dependent. If you assign a scope to a bean, it is bound to the appropriate context. The producer method in this example is only called once per session.
@Produces @Preferred @SessionScoped
public PaymentStrategy getPaymentStrategy() {
...
}
@Produces @Preferred @SessionScoped
public PaymentStrategy getPaymentStrategy() {
...
}
Example 11.12. Use an injection inside a producer method
Note
Producer methods allow you to inject non-bean objects and change your code dynamically.
11.2.7. Named Beans and Alternative Beans 复制链接链接已复制到粘贴板!
11.2.7.1. About Named Beans 复制链接链接已复制到粘贴板!
@Named annotation. Naming a bean allows you to use it directly in Java Server Faces (JSF).
@Named annotation takes an optional parameter, which is the bean name. If this parameter is omitted, the lower-cased bean name is used as the name.
11.2.7.2. Use Named Beans 复制链接链接已复制到粘贴板!
Use the
@Namedannotation to assign a name to a bean.Copy to Clipboard Copied! Toggle word wrap Toggle overflow The bean name itself is optional. If it is omitted, the bean is named after the class name, with the first letter decapitalized. In the example above, the default name would begreeterBean.Use the named bean in a JSF view.
<h:form> <h:commandButton value="Welcome visitors" action="#{greeter.welcomeVisitors}"/> </h:form><h:form> <h:commandButton value="Welcome visitors" action="#{greeter.welcomeVisitors}"/> </h:form>Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Your named bean is assigned as an action to the control in your JSF view, with a minimum of coding.
11.2.7.3. About Alternative Beans 复制链接链接已复制到粘贴板!
Example 11.13. Defining Alternatives
beans.xml file.
11.2.7.4. Override an Injection with an Alternative 复制链接链接已复制到粘贴板!
Alternative beans let you override existing beans. They can be thought of as a way to plug in a class which fills the same role, but functions differently. They are disabled by default. This task shows you how to specify and enable an alternative.
Procedure 11.5. Override an Injection
TranslatingWelcome class in your project, but you want to override it with a "mock" TranslatingWelcome class. This would be the case for a test deployment, where the true Translator bean cannot be used.
Define the alternative.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Substitute the alternative.
To activate the substitute implementation, add the fully-qualified class name to yourMETA-INF/beans.xmlorWEB-INF/beans.xmlfile.<beans> <alternatives> <class>com.acme.MockTranslatingWelcome</class> </alternatives> </beans><beans> <alternatives> <class>com.acme.MockTranslatingWelcome</class> </alternatives> </beans>Copy to Clipboard Copied! Toggle word wrap Toggle overflow
The alternative implementation is now used instead of the original one.
11.2.8. Stereotypes 复制链接链接已复制到粘贴板!
11.2.8.1. About Stereotypes 复制链接链接已复制到粘贴板!
- default scope
- a set of interceptor bindings
- all beans with the stereotype have defaulted bean EL names
- all beans with the stereotype are alternatives
@Named annotation, any bean it is placed on has a default bean name. The bean may override this name if the @Named annotation is specified directly on the bean. For more information about named beans, see Section 11.2.7.1, “About Named Beans”.
11.2.8.2. Use Stereotypes 复制链接链接已复制到粘贴板!
Without stereotypes, annotations can become cluttered. This task shows you how to use stereotypes to reduce the clutter and streamline your code. For more information about what stereotypes are, see Section 11.2.8.1, “About Stereotypes”.
Example 11.14. Annotation clutter
Procedure 11.6. Define and Use Stereotypes
Define the stereotype,
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Use the stereotype.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Stereotypes streamline and simplify your code.
11.2.9. Observer Methods 复制链接链接已复制到粘贴板!
11.2.9.1. About Observer Methods 复制链接链接已复制到粘贴板!
11.2.9.2. Transactional Observers 复制链接链接已复制到粘贴板!
public void refreshCategoryTree(@Observes(during = AFTER_SUCCESS) CategoryUpdateEvent event) { ... }
public void refreshCategoryTree(@Observes(during = AFTER_SUCCESS) CategoryUpdateEvent event) { ... }
- IN_PROGRESS: By default, observers are invoked immediately.
- AFTER_SUCCESS: Observers are invoked after the completion phase of the transaction, but only if the transaction completes successfully.
- AFTER_FAILURE: Observers are invoked after the completion phase of the transaction only if the transaction fails to complete successfully.
- AFTER_COMPLETION: Observers are invoked after the completion phase of the transaction.
- BEFORE_COMPLETION: Observers are invoked before the completion phase of the transaction.
11.2.9.3. Fire and Observe Events 复制链接链接已复制到粘贴板!
Example 11.15. Fire an event
Example 11.16. Fire an event with a qualifier
Example 11.17. Observe an event
@Observes annotation.
Example 11.18. Observe a qualified event
11.2.10. Interceptors 复制链接链接已复制到粘贴板!
11.2.10.1. About Interceptors 复制链接链接已复制到粘贴板!
Interception points
- business method interception
- A business method interceptor applies to invocations of methods of the bean by clients of the bean.
- lifecycle callback interception
- A lifecycle callback interceptor applies to invocations of lifecycle callbacks by the container.
- timeout method interception
- A timeout method interceptor applies to invocations of the EJB timeout methods by the container.
11.2.10.2. Use Interceptors with CDI 复制链接链接已复制到粘贴板!
Example 11.19. Interceptors without CDI
- The bean must specify the interceptor implementation directly.
- Every bean in the application must specify the full set of interceptors in the correct order. This makes adding or removing interceptors on an application-wide basis time-consuming and error-prone.
Procedure 11.7. Use interceptors with CDI
Define the interceptor binding type.
@InterceptorBinding @Retention(RUNTIME) @Target({TYPE, METHOD}) public @interface Secure {}@InterceptorBinding @Retention(RUNTIME) @Target({TYPE, METHOD}) public @interface Secure {}Copy to Clipboard Copied! Toggle word wrap Toggle overflow Mark the interceptor implementation.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Use the interceptor in your business code.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Enable the interceptor in your deployment, by adding it to
META-INF/beans.xmlorWEB-INF/beans.xml.Copy to Clipboard Copied! Toggle word wrap Toggle overflow The interceptors are applied in the order listed.
CDI simplifies your interceptor code and makes it easier to apply to your business code.
11.2.11. About Decorators 复制链接链接已复制到粘贴板!
@Decorator. To invoke a decorator in a CDI application, it must be specified in the beans.xml file.
Example 11.20. Example Decorator
@Delegate injection point to obtain a reference to the decorated object.
11.2.12. About Portable Extensions 复制链接链接已复制到粘贴板!
- integration with Business Process Management engines
- integration with third-party frameworks such as Spring, Seam, GWT or Wicket
- new technology based upon the CDI programming model
- Providing its own beans, interceptors and decorators to the container
- Injecting dependencies into its own objects using the dependency injection service
- Providing a context implementation for a custom scope
- Augmenting or overriding the annotation-based metadata with metadata from some other source
11.2.13. Bean Proxies 复制链接链接已复制到粘贴板!
11.2.13.1. About Bean Proxies 复制链接链接已复制到粘贴板!
Java types that cannot be proxied by the container
- Classes which do not have a non-private constructor with no parameters
- Classes which are declared
finalor have afinalmethod - Arrays and primitive types
11.2.13.2. Use a Proxy in an Injection 复制链接链接已复制到粘贴板!
A proxy is used for injection when the lifecycles of the beans are different from each other. The proxy is a subclass of the bean that is created at run-time, and overrides all the non-private methods of the bean class. The proxy forwards the invocation onto the actual bean instance.
PaymentProcessor instance is not injected directly into Shop. Instead, a proxy is injected, and when the processPayment() method is called, the proxy looks up the current PaymentProcessor bean instance and calls the processPayment() method on it.
Example 11.21. Proxy Injection