Why do I need these no-args constructors???
What happens if a session scoped bean gets injected into an application scoped bean? How does the application scoped bean get the correct session scoped bean instance for each request? Wouldn't the session scoped bean leak out into other requests? How does that work? In order to facilitate scoping, CDI uses what is known as a proxy. When CDI injects a non-dependent scoped bean into another object, it does not inject the bean directly. Instead, it subclasses that bean to create what is known as a proxy. Whenever a method is called on the proxy, it asks the CDI runtime to look up the correct bean for that particular scope (if it's request scoped, get the bean for that request. If it's session scoped, get the bean for that session. etc.), and then forwards the call to the real object, returning any result for non-void methods. This means that the following is an okay thing to do:
@ApplicationScoped
public class ApplicationScopedClass {
private final RequestScopedClass requestScopedClass;
@Inject
public ApplicationScopedClass(RequestScopedClass requestScopedClass) {
this.requestScopedClass = requestScopedClass;
}
public ApplicationScopedClass() {
}
public doSomething() {
requestScopedClass.doSomethingRequestSpecific(); //This works, because of the proxy
}
}
However, the in order for a class to legally subclass another class in Java, it must have a valid constructor. And a valid constructor must call either another constructor on the class, or the parent class' constructor (e.g. super()
). In order to simplify this subclassing, the CDI spec requires any non-dependent scoped bean to provide a public no-args constructor, so that the runtime doesn't have to try to guess at what to do with a class which needs to be proxied.