Re: JSF 2.3 Table 5-3 JSF artifacts eligible for injection - Constructor Injection question
Hello Paul,
I secured some time to think about this today. If you like, you can skip right to the CONCLUSION by searching for CONCLUSION:. First, the general rationale for ctor injection is adequately described in this stackoverflow post https://stackoverflow.com/questions/19381846/why-use-constructor-over-setter-injection-in-cdi . Given that rationale, ctor injection seems to make the most sense for domain objects, rather than the classes in Table 5-3. Let's take a look at each of the classes in Table 5-3 and ask ourselves if it makes sense to have ctor injection for that class, and what it would mean to have ctor injection. I will also suggest a potential use for ctor injection for a future revision of JSF. javax.el.ELResolver Section 5.5.2.1 states "ELResolver instances have application lifetime and scope." Since this is lifetime scope, we really don't know what would make sense to pass to a ctor injection. Future: Perhaps the presence of @Inject with an ELResolver argument could be used to provide a reference to the parent ELResolver in the chain. javax.faces.application.ApplicationFactory Section 7.2 states, "A single instance of javax.faces.application.ApplicationFactory must be made available to each JSF- based web application running in a servlet or portlet container." Since this is a singleton, what would make sense to pass to the ctor? Also, this class is mentioned in section 11.4.7 Delegating Implementation Support. In that section, the spec says, "For all of these artifacts, the decorator design pattern is leveraged, so that if one provides a constructor that takes a single argument of the appropriate type, the custom implementation receives a reference to the implementation that was previously fulfilling the role." So in this sense we already support ctor injection for this class. Future occurrences of this explanation will be labeled as "See 11.4.7 Delegating Implementation Support" Future: Perhaps this @Inject could be passed the javax.enterprise.inject.spi.CDI. javax.faces.application.NavigationHandler Section 7.4.1 states, "A single NavigationHandler instance is responsible for consuming the logical outcome returned by an application action that was invoked, along with additional state information that is available from the FacesContext instance for the current request, and (optionally) selecting a new view to be rendered." So, this is a singleton. See 11.4.7 Delegating Implementation Support javax.faces.application.ResourceHandler This is also an application singleton. See 11.4.7 Delegating Implementation Support. See 11.4.7 Delegating Implementation Support Future: Perhaps this @Inject could be passed the default ViewDeclarationLanguage? javax.faces.application.StateManager Section 7.8 makes it clear the StateManager is an application singleton, therefore ctor injection doesn't make a lot of sense. See 11.4.7 Delegating Implementation Support Future: Perhaps this @Inject could be passed the default ViewDeclarationLanguage? javax.faces.component.visit.VisitContextFactory This is a singleton factory. I don't see what it would be useful to pass for ctor injection. See 11.4.7 Delegating Implementation Support javax.faces.context.ExceptionHandlerFactory This is a singleton factory. I don't see what it would be useful to pass for ctor injection. See 11.4.7 Delegating Implementation Support javax.faces.context.ExternalContextFactory Section 6.8 states, "A single instance of javax.faces.context.ExternalContextFactory must be made available to each JSF-based web application running in a servlet or portlet container." This is a singleton factory. I don't see what it would be useful to pass for ctor injection. See 11.4.7 Delegating Implementation Support javax.faces.context.FacesContextFactory This is a singleton factory. Future: Since the default one simply turns around and calls the exceptionHandlerFactory() and externalContextFactory, it would make sense to allow these to be @Inject ctor injected, but that would be a new feature. See 11.4.7 Delegating Implementation Support javax.faces.context.PartialViewContextFactory Since this is an application singletion, I don't know it would make sense to pass for ctor injection. javax.faces.event.ActionListener See 11.4.7 Delegating Implementation Support javax.faces.event.SystemEventListener This one is implemented by application code. Future: Perhaps ctor injection could be passed the Application? javax.faces.lifecycle.ClientWindowFactory This is a singleton factory. Future: the default impl gets a handle to the Application and subscribes to the PostConstructApplicationEvent. Perhaps ctor injection could be useful to pass the Application. javax.faces.lifecycle.LifecycleFactory This is a singleton factory. Future: Perhaps this @Inject could be passed the javax.enterprise.inject.spi.CDI. See 11.4.7 Delegating Implementation Support javax.faces.event.PhaseListener These are application singletons. Future: Perhaps ctor injection could pass a reference to the Application, or the Lifecycle? javax.faces.render.RenderKitFactory This is a singleton factory. Future: Perhaps ctor injection could pass a reference to the Application. See 11.4.7 Delegating Implementation Support javax.faces.view.ViewDeclarationLanguageFactory This is a singleton factory. Future: Perhaps ctor injection could pass a reference to the Application. javax.faces.view.facelets.FaceletCacheFactory This is a singleton factory. Future: Perhaps ctor injection could pass a reference to the Application. javax.faces.view.facelets. TagHandlerDelegateFactory This is a singleton factory. Future: Perhaps ctor injection could pass a reference to the Application. CONCLUSION: In conclusion I will propose the JSF maintenance lead to make the following change to the spec. In section 5.4.1, please change the text In addition to managed beans being injectable in this manner, the following JSF artifacts are also injectable. to be instead In addition to managed beans being injectable in this manner, the following JSF artifacts are also injectable via field and setter injection. Constructor injection does not make sense for these artifacts and is not supported. Thanks, Ed
|
|