JAVA EE CDI Scopes, EJBs and managed beans seriali

2019-02-21 04:54发布

问题:

Have some questions regarding scopes, ejbs, and managed beans.

  1. Are scopes (javax.enterprise.context.ApplicationScope, javax.enterprise.context.SessionScope) only for EJBs? Or are they for all managed beans? Until today I was pretty sure it was for all managed beans.
  2. In my application we have:

    @ApplicationScoped
    public class MyClass implements MyNonSerializableInterface {
      @Inject  
      private transient NonSerializableLogger transientLogger;
      @Inject
      private NonSerializableLogger logger;
     ...
    }
    

    and some manager:

    @Singleton
    public class SomeManager {
        @Inject private MyClass myClass;  
    
    }
    

    and a web service:

    @Path("some")
    public class SomeWebService {
        @Inject private SomeManager;
    
    }
    

The container (deploy time) or compiler does not complain about it, is that normal?

I thought that:

"Beans that use session, application, or conversation scope must be serializable, but beans that use request scope do not have to be serializable."JAVA EE Using Scopes

MyClass should implement Serializable or not? Could we say that because the managed bean is injected into a @Singleton, serialization never occurs? Therefore no serialization error is shown at deploy time?

  1. If Yes: If I make MyClass @ApplicationScoped and @Stateful and inject it in SomeManager using @EJB, than at deployment time I do get an error about serialization..
  2. If No: Why don't I get some NullPointerExceptions for the transient Logger (due to pasivitation/activation)?

回答1:

CDI scopes are evaluated in the context of CDI container. That said, the designers of CDI specification ensured that it is operable with EJB and jsf Managed Bean. That said.

  1. CDI scopes are ideally context-of-usage-sensitive. @ApplicationScoped means that the CDI bean shall live from the instance it is created to the end of the application. It is managed by the CDI container and has absolutely nothing to do with EJB beans. But because of interoperability with EJB, it can be injected (@Inject) into an EJB @Singleton bean. There is no requirement in EJB spec, nor CDI spec that either @Singleton bean or @ApplicationScope bean be serializable. And since this is an application wide instance, it requires no passivation.

  2. @SessionScope uses whichever semantics of a session that current container wishes. for example in a jsf application, it will generally be scoped to the lifetime of the HttpSession, but in an EJB container without HttpSession, the container wont attach any meaningful session sematics. It might decide to be a per @Stateless transaction or anything it so wishes. Since sessions can be serialized, the spec generally requires that @SessionScoped beans be serializable, but the bean at which the injectionpoint is defined, if not @SessionScoped, need not be serializable.

  3. @RequestScope also follows the semantics of single execution of "atomic" action, e.g. httprequest. In a web container, it will generally be associated with HttpRequest, and there is no requirement that it be serializable. In a non-web context, it could be associated with a per invocation, or even transaction boundary (in case of injection into EJB) or it will default to @Dependent scope at the injection point, when no meaningful scope can be attributed.

That said, any CDI bean can be injected into any EJB bean. Generally in an EJB container which is not associated with a web container, @Dependent and @ApplicationScope are the only scopes that would have any meaningful usages.