7 Using Java EE Annotations and Dependency Injection

The following sections describe the concepts of MetaData annotation and dependency injection:

Annotation Processing

With Java EE annotations, the standard application.xml and web.xml deployment descriptors are optional. The Java EE programming model uses the JDK 5.0 annotations feature for Web containers, such as EJBs, servlets, Web applications, and JSPs (see https://download.oracle.com/javaee/5/api/).

Annotations simplify the application development process by allowing developers to specify within the Java class itself how the application component behaves in the container, requests for dependency injection, and so on. Annotations are an alternative to deployment descriptors that were required by older versions of Enterprise applications (Java EE 1.4 and earlier).

Annotation Parsing

The application components can use annotations to define their needs. Annotations reduce or eliminate the need to deal with deployment descriptors. Annotations simplify the development of application components. The deployment descriptor can still override values defined in the annotation. One usage of annotations is to define fields or methods that need Dependency Injection (DI). Annotations are defined on the POJO (plain old Java object) component classes like the EJB or the servlet.

An annotation on a field or a method can declare that fields/methods need injection, as described in Dependency Injection of Resources. Annotations may also be applied to the class itself. The class-level annotations declare an entry in the application component's environment but do not cause the resource to be injected. Instead, the application component is expected to use JNDI or component context lookup method to lookup the entry. When the annotation is applied to the class, the JNDI name and the environment entry type must be specified explicitly.

Deployment View of Annotation Configuration

The Java EE Deployment API [JSR88] provides a way for developers to examine deployment descriptors. For example, consider an EJB Module that has no deployment descriptors. Assuming that it has some classes that have been declared as EJBs using annotations, a user of Session Helper will still be able to deal with the module as if it had the deployment descriptor. So the developer can modify the configuration information and it will be written out in a deployment plan. During deployment, such a plan will be honored and will override information from annotations.

Compiling Annotated Classes

The WebLogic Server utility appc (and its Ant equivalent wlappc) and Appmerge support metadata annotations. The appmerge and appc utilities take an application or module as inputs and process them to produce an output application or module respectively. When used with -writeInferredDescriptors flag, the output application/module will contain deployment descriptors with annotation information. The descriptors will also have the metadata-complete attribute set to true, as no annotation processing needs to be done if the output application or module is deployed directly. However, setting of metadata-complete attribute to true will also restrict appmerge and appc from processing annotations in case these tools are invoked on a previously processed application or module.

The original descriptors must be preserved in such cases to with an .orig suffix. If a developer wants to reapply annotation processing on the output application, they must restore the descriptors and use the -writeInferredDescriptors flag again. If appmerge or appc is used with -writeInferredDescriptors on an Enterprise application for which no standard deployment descriptor exists, the descriptor will be generated and written out based on the inference rules in the Java EE specification.

For more information on using appc, see weblogic.appc Reference. For more information on using appmerge, see Using weblogic.appmerge to Merge Libraries.

Dynamic Annotation Updates

Deployed modules can be updated using update deployment operation. If such an update has changes to deployment descriptor or updated classes, the container must consider annotation information again while processing the new deployment descriptor.

Containers use the descriptor framework's two-phase update mechanism to check the differences between the current and proposed descriptors. This mechanism also informs the containers about any changes in the non-dynamic properties. The containers then deal with such non-dynamic changes in their own specific ways. The container must perform annotation processing on the proposed descriptor to make sure that it is finding the differences against the right reference.

Similarly, some of the classes from a module could be updated during an update operation. If the container knows that these classes could affect configuration information through annotations, it makes sure that nothing has changed.

Dependency Injection of Resources

Dependency injection (DI) allows application components to declare dependencies on external resources and configuration parameters via annotations. The container reads these annotations and injects resources or environment entries into the application components. Dependency injection is simply an easier-to-program alternative to using the javax interfaces or JNDI APIs to look up resources.

A field or a method of an application component can be annotated with the @Resource annotation. Note that the container will unbox the environment entry as required to match it to a primitive type used for the injection field or method. Example 7-1 illustrates how an application component uses the @Resource annotation to declare environment entries.

Example 7-1 Dependency Injection of Environment Entries

     // fields
     
     // The maximum number of tax exemptions, configured by the Deployer.
     @Resource int maxExemptions;
     // The minimum number of tax exemptions, configured by the Deployer.
     @Resource int minExemptions;
     
     …..
     }

In the above code the @Resource annotation has not specified a name; therefore, the container would look for an env-entry name called <class-name>/maxExemptions and inject the value of that entry into the maxExemptions variable. The field or method may have any access qualifier (public, private, etc.). For all classes except application client main classes, the fields or methods must not be static. Because application clients use the same life cycle as Java EE applications, no instance of the application client main class is created by the application client container. Instead, the static main method is invoked. To support injection for the application client main class, the fields or methods annotated for injection must be static.

Application Life Cycle Annotation Methods

An application component may need to perform initialization of its own after all resources have been injected. To support this case, one method of the class can be annotated with the @PostConstruct annotation. This method will be called after all injections have occurred and before the class is put into service. This method will be called even if the class doesn't request any resources to be injected. Similarly, for classes whose life cycle is managed by the container, the @PreDestroy annotation can be applied to one method that will be called when the class is taken out of service and will no longer be used by the container. Each class in a class hierarchy may have @PostConstruct and @PreDestroy methods.

The order in which the methods are called matches the order of the class hierarchy, with methods on a superclass being called before methods on a subclass. From the Java EE side only the application client container is involved in invoking these life cycle methods for Java EE clients. The life cycle methods for Java EE clients must be static. The Java EE client just supports the @PostConstruct callback.

Standard JDK Annotations

This section provides reference information about the following annotations:

For detailed information about EJB-specific annotations for WebLogic Server Enterprise JavaBeans, see Programming WebLogic Enterprise JavaBeans, Version 3.0 for Oracle WebLogic Server.

For detailed information about web component-specific annotations WebLogic Server applications, see "WebLogic Annotation for Web Components" in Developing Web Applications, Servlets, and JSPs for Oracle WebLogic Server.

javax.annotation.PostConstruct

Target: Method

Specifies the life cycle callback method that the application component should execute before the first business method invocation and after dependency injection is done to perform any initialization. This method will be called after all injections have occurred and before the class is put into service. This method will be called even if the class doesn't request any resources to be injected.

You must specify a @PostConstruct method in any component that includes dependency injection.

Only one method in the component can be annotated with this annotation.

The method annotated with @PostConstruct must follow these requirements:

  • The method must not have any parameters, except in the case of EJB interceptors, in which case it takes an javax.interceptor.InvocationContext object as defined by the EJB specification.

  • The return type of the method must be void.

  • The method must not throw a checked exception.

  • The method may be public, protected, package private or private.

  • The method must not be static except for the application client.

  • The method may be final or non-final, except in the case of EJBs where it must be non-final.

  • If the method throws an unchecked exception the class must not be put into service. In the case of EJBs, the method annotated with PostConstruct can handle exceptions and cleanup before the bean instance is discarded.

This annotation does not have any attributes.

javax.annotation.PreDestroy

Target: Method

Specifies the life cycle callback method that signals that the application component is about to be destroyed by the container. You typically apply this annotation to methods that release resources that the class has been holding.

Only one method in the bean class can be annotated with this annotation.

The method annotated with @PreDestroy must follow these requirements:

  • The method must not have any parameters, except in the case of EJB interceptors, in which case it takes an javax.interceptor.InvocationContext object as defined by the EJB specification.

  • The return type of the method must be void.

  • The method must not throw a checked exception.

  • The method may be public, protected, package private or private.

  • The method must not be static except for the application client.

  • The method may be final or non-final, except in the case of EJBs where it must be non-final.

  • If the method throws an unchecked exception the class must not be put into service. In the case of EJBs, the method annotated with PreDestroy can handle exceptions and cleanup before the bean instance is discarded.

This annotation does not have any attributes.

javax.annotation.Resource

Target: Class, Method, Field

Specifies a dependence on an external resource, such as a JDBC data source or a JMS destination or connection factory.

If you specify the annotation on a field or method, the application component injects an instance of the requested resource into the bean when the bean is initialized. If you apply the annotation to a class, the annotation declares a resource that the component will look up at runtime.

Attributes

Table 7-1 Attributes of the javax.annotation.Resource Annotation

Name Description Data Type Required?

name

Specifies the JNDI name of the resource.

If you apply the @Resource annotation to a field, the default value of the name attribute is the field name, qualified by the class name. If you apply it to a method, the default value is the component property name corresponding to the method, qualified by the class name. If you apply the annotation to class, there is no default value and thus you are required to specify the attribute.

String

No

type

Specifies the Java data type of the resource.

If you apply the @Resource annotation to a field, the default value of the type attribute is the type of the field. If you apply it to a method, the default is the type of the component property. If you apply it to a class, there is no default value and thus you are required to specify this attribute.

Class

No

authenticationType

Specifies the authentication type to use for the resource.

Valid values for this attribute are:

  • AuthenticationType.CONTAINER

  • AuthenticationType.APPLICATION

Default value is AuthenticationType.CONTAINER

AuthenticationType

No

shareable

Indicates whether a resource can be shared between this component and other components.

Valid values for this attribute are true and false. Default value is true.

Boolean

No

mappedName

Specifies a WebLogic Server-specific name to which the component reference should be mapped.

However, if you do not specify a JNDI name in the WebLogic deployment descriptor file, then the value of mappedName will always be used as the JNDI name to look up. For example:

@Resource(mappedName = "http://www.bea.com";)

URL url;

@Resource(mappedName="customerDB")

DataSource db;

@Resource(mappedName = "jms/ConnectionFactory")

ConnectionFactory connectionFactory;

@Resource(mappedName = "jms/Queue")

Queue queue;

In other words, MappedName is honored as JNDI name only when there is no JNDI name specified elsewhere, typically in the WebLogic deployment descriptor file.

String

No

description

Specifies a description of the resource.

String

No


javax.annotation.Resources

Target: Class

Specifies an array of @Resource annotations. Since repeated annotations are not allowed, the Resources annotation acts as a container for multiple resource declarations.

Attributes

Table 7-2 Attributes of the javax.annotation.Resources Annotation

Name Description Data Type Required?

value

Specifies the array of @Resource annotations.

Resource[]

Yes


Standard Security-Related JDK Annotations

This section provides reference information about the following annotations:

javax.annotation.security.DeclareRoles

Target: Class

Defines the security roles that will be used in the Java EE container.

You typically use this annotation to define roles that can be tested from within the methods of the annotated class, such as using the isUserInRole method. You can also use the annotation to explicitly declare roles that are implicitly declared if you use the @RolesAllowed annotation on the class or a method of the class.

You create security roles in WebLogic Server using the Administration Console. For details, see "Manage Security Roles".

Attributes

Table 7-3 Attributes of the javax.annotation.security.DeclareRoles Annotation

Name Description Data Type Required?

value

Specifies an array of security roles that will be used in the Java EE container.

String[]

Yes


javax.annotation.security.DenyAll

Target: Method

Specifies that no security role is allowed to access the annotated method, or in other words, the method is excluded from execution in the Java EE container.

This annotation does not have any attributes.

javax.annotation.security.PermitAll

Target: Method

Specifies that all security roles currently defined for WebLogic Server are allowed to access the annotated method.

This annotation does not have any attributes.

javax.annotation.security.RolesAllowed

Target: Class, Method

Specifies the list of security roles that are allowed to access methods in the Java EE container.

If you specify it at the class-level, then it applies to all methods in the application component. If you specify it at the method-level, then it only applies to that method. If you specify the annotation at both the class- and method-level, the method value overrides the class value.

You create security roles in WebLogic Server using the Administration Console. For details, see "Manage Security Roles".

Attributes

Table 7-4 Attributes of the javax.annotation.security.RolesAllowed Annotation

Name Description Data Type Required?

value

List of security roles that are allowed to access methods of the Java EE container.

String[]

Yes


javax.annotation.security.RunAs

Target: Class

Specifies the security role which actually executes the Java EE container.

The security role must exist in the WebLogic Server security realm and map to a user or group. For details, see "Manage Security Roles".

Attributes

Table 7-5 Attributes of the javax.annotation.security.RunAs Annotation

Name Description Data Type Required?

value

Specifies the security role that the Java EE container should run as.

String

Yes