How Variable of an Interface is Working in JAVA and Calling the Methods of Interface?
-
22-12-2019 - |
Question
I know all the following rules of Java Interfaces:
- You cannot instantiate an interface.
- An interface does not contain any constructors.
- All of the methods in an interface are abstract.
- An interface cannot contain instance fields. The only fields that can appear in an interface must be declared both static and final.
- An interface is not extended by a class; it is implemented by a class.
- An interface can extend multiple interfaces.
Now my question is how we are creating an variable of interface EntityManager and using its methods like given code below:
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateful
public class Movies {
@PersistenceContext(unitName = "movie-unit")
private EntityManager em; // Here declaring a variable of an Interface
public void addMovie(Movie movie) throws Exception {
em.persist(movie); // Here using variable of an Interface to call its method
}
}
Please put some light on this so that I can clear up my understanding of how this code is working!
Solution
You're not creating anything here, the container is. All you've done is declare a dependency to be injected, this is how DI works in JavaEE. A very simplistic view of what is happening:
Your
Movies
EJB is proxied by the containerThe proxy introspects your class and discovers the annotation you've declared, along with the field you've declared it on
The container provides an instance of the
EntityManager
to the proxy, which in turn makes it available to your implementation.
Presto: Instant EntityManager
. Notice how little you're involved in the process?
OTHER TIPS
The only thing you seem to be missing is the dependency injection. Here,
@PersistenceContext(unitName = "movie-unit")
private EntityManager em; // <-- this is an instance of a class that implements the
// EntityManager interface. Interfaces (as you note)
// cannot be directly instantiated.
The container uses field inspection and "sees" the @PersistenceContext(unitName = "movie-unit")
annotation. It then injects the appropriate instance. Per the PersistenceContext
Javadoc,
Expresses a dependency on a container-managed
EntityManager
and its associated persistence context.
The container manages it.