Resource Injection vs. Dependency Injection Explained!
Join the DZone community and get the full member experience.
Join For FreeFellow geeks, the following article provides an overview of injection in Java EE and describes the two injection mechanisms provided by the platform: Resource Injection and Dependency Injection.
Java EE provides injection mechanisms that enable our objects to obtain the references to resources and other dependencies without having to instantiate them directly (explicitly with ‘new’ keyword). We simply declare the needed resources & other dependencies in our classes by drawing fields or methods with annotations that denotes the injection point to the compiler.
The container then provides the required instances at runtime. The advantage of Injection is that it simplifies our code and decouples it from the implementations of its dependencies.
Note should be given for the fact that Dependency Injection is a specification (also a design pattern) and Context and Dependency Injection (CDI) is an implementation andJava standard for DI.
The following topics are discussed here:
· Resource Injection
· Dependency Injection
· Difference between Context and Dependency Injection
1. Resource Injection
One of the simplification features of Java EE is the implementation of basic Resource Injection to simplify web and EJB components.
Resource injection enables you to inject any resource available in the JNDI namespace into any container-managed object, such as a servlet, an enterprise bean, or a managed bean. For eg, we can use resource injection to inject data sources, connectors, or any other desired resources available in the JNDI namespace.
The type we’ll use for the reference to the instance happen to be injected is usually an interface, which would decouple our code from the implementation of the resource.
For better understanding of the above statement let’s take a look at the example.
The resource injection can be performed in the following three ways:
· Field Injection
· Method Injection
· Class injection
Now, the javax.annotation.Resource annotation is used to declare a reference to a resource. So before proceeding, let’s learn few elements of @Resource annotation.
@Resource has the following elements:
· name: The JNDI name of the resource
· type: The Java type of the resource
· authenticationType: The authentication type to use for the resource
· shareable: Indicates whether the resource can be shared
· mappedName: A non-portable, implementation-specific name to which the resource should be mapped
· description: The description of the resource
Thenameelement is the JNDI name of the resource, and is optional for field- and method-based injection. For field injection, d defaultnameis the field name. For method-based injection, the defaultnameis the JavaBeans property name based on the method.
The‘name’ and ‘type’element must be specified for class injection.
Thedescriptionelement is the description of the resource (optional).
Let’s hop on to the example now.
Field Injection:
To use field-based resource injection, declare a field and annotate it with the @Resource annotation. The container will refer the name and type of the resource if the name and type elements are not specified. If you do specify the type element, it must match the field’s type declaration.
package com.example; public class SomeClass { @Resource private javax.sql.DataSource myDB; ... }
In the code above, the container infers the name of the resource based on the class name and the field name: com.example.SomeClass/myDB. The inferred type isjavax.sql.DataSource.class.
package com.example; public class SomeClass { @Resource(name="customerDB") private javax.sql.DataSource myDB; ... }
In the code above, the JNDI name is customerDB, and the inferred type is javax.sql.DataSource.class.
Method Injection:
To use method injection, declare a setter method and preceding with the @Resource annotation. The container will itself refer the name and type of the resource if in case it is not specified by programmer. The setter method must follow the JavaBeans conventions for property names: the method name must begin with set, have a void return type, and only one parameter (needless to say :P). Anyways, if you do specify the return type, it must match the field’s type declaration.
package com.example; public class SomeClass { private javax.sql.DataSource myDB; ... @Resource private void setMyDB(javax.sql.DataSource ds) { myDB = ds; } ... }
In the code above, the container refers the name of the resource according to the class name and the field name: com.example.SomeClass/myDB. The type which is javax.sql.DataSource.class.
package com.example; public class SomeClass { private javax.sql.DataSource myDB; ... @Resource (name="customerDB") private void setMyDB (javax.sql.DataSource ds) { myDB = ds; } ... }
In the code above, the JNDI name is customerDB, and the inferred type is javax.sql.DataSource.class.
Class Injection:
To use class-based injection, decorate the class with a @Resource annotation, and set the requiredname and type elements.
@Resource(name="myMessageQueue", type="javax.jms.ConnectionFactory") public class SomeMessageBean { ... }
Declaring Multiple Resources
The @Resources annotation is used to group together multiple @Resource declarations for class injection only.
@Resources({ @Resource(name="myMessageQueue", type="javax.jms.ConnectionFactory"), @Resource(name="myMailSession", type="javax.mail.Session") }) public class SomeMessageBean { ... }
The code above shows the @Resources annotation containing two @Resource declarations. One is a JMS (Java Messagin Service) message queue, and the other is a JavaMail session.
2. Dependency Injection
Dependency injection enables us to turn regular Java classes into managed objects and to inject them into any other managed object (objects wich are managed by the container).
Using DI, our code can declare dependencies on any managed object. The container automatically provides instances of these dependencies at the injection points at runtime, n it also manages the lifecycle of these instances right from class loading to releasing it for Garbage Collection.
Dependency injection in Java EE defines scopes. For eg, a managed object that is only happen to respond to a single client request (such as a currency converter) has a different scope than a managed object that is needed to process multiple client requests within a session (such as a shopping cart). We can define managed objects (also called managed beans) so that we can later inject by assigning a scope to a needed class:
@javax.enterprise.context.RequestScoped public class CurrencyConverter { ... } Use the javax.inject.Inject annotation to inject managed beans; for example: public class MyServlet extends HttpServlet { @Inject CurrencyConverter cc; ... }
Umlike resource injection, dependency injection is typesafe because it resolves by type. To decouple our code from the implementation of the managed bean, we can reference the injected instances using an interface type and have our managed bean (regular class controlled by container) implement that interface.
I wouldn’t like to discuss more on DI or better saying CDI since we already have a great article published on this.
3. Difference between Resource Injection and Dependency Injection
The differences between the RI and DI are listed below.
1. Resource Injection can inject JNDI Resources directly whereas Dependency Injection cannot.
2. Dependency Injection can inject Regular Classes (managed bean) directly whereas Resource Injection cannot.
3. Resource Injection resolves by resource name whereas Dependency Injectin resolves by type.
4. Dependency Injection is typesafe whereas Resoiurce Injection is not.
Conclusion:
Thus we learnt concept on types on Injection in Java EE and the differences between them. Just a brief. There’s more to come
Opinions expressed by DZone contributors are their own.
Comments