[ 
https://issues.apache.org/jira/browse/MYFACES-3786?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13791143#comment-13791143
 ] 

Leonardo Uribe edited comment on MYFACES-3786 at 10/10/13 3:27 AM:
-------------------------------------------------------------------

There is a confusion behind how CDI affects JSF artifacts. To be clear, JSF 
artifacts are managed by JSF, not by CDI. Why? because in this case those 
objects are not bound to an specific scope inside CDI, and there is no 
delegation of the instantiation process to CDI. 

In that sense, the existing rules related to CDI beans like hold the 
CreationalContext until destroy and so on does not apply. What we need here is 
implement these 3 steps:

- Injection
- invoke PostConstruct methods
- invoke PreDestroy methods

There is already an SPI interface for that in JSF called LifecycleProvider. The 
idea is we have an interface called LifecycleProvider2 with these methods:

Object newInstance(String className)
void postConstruct(Object o)
void destroyInstance(Object o)

This has worked well for a long time, and server vendors have usually a custom 
implementation of this interface. This is used to handle servlet 2.5 annotation 
in jsf managed beans (this is the clue left in JSF 2.2 spec section 5.4.1). 

Unfortunately, LifecycleProvider2 was an interface added to fix an issue and to 
avoid break things. As part of the cleanup for JSF 2.2 we need to provide a new 
SPI interface for this point. 

Taking into account the CDI InjectionTarget:

void    inject(T instance, CreationalContext<T> ctx) 
void    postConstruct(T instance) 
void    preDestroy(T instance) 

I would like to add the following spi interface:

public abstract class org.apache.myfaces.spi.InjectionLifecycleProvider
{
    public abstract Object createNewInstanceAndInject(String className) throws 
InjectionLifecycleProviderException;
    public abstract void inject(Object instance) throws 
InjectionLifecycleProviderException;
    public abstract void postConstruct(Object instance) throws 
InjectionLifecycleProviderException;
    public abstract void preDestroy(Object instance) throws 
InjectionLifecycleProviderException;
}

Other model to keep in mind is the one used by Mojarra for the same case:

public interface  InjectionProvider {
   public void inject(Object managedBean) throws InjectionProviderException;
   public void invokePreDestroy(Object managedBean) throws 
InjectionProviderException;
   public void invokePostConstruct(Object managedBean) throws 
InjectionProviderException;
}

Basically the diffence against the implementation in Mojarra is the use of an 
abstract class instead of a interface and the addition of a method 
createNewInstanceAndInject(String className), which most of the time comes in 
handy (and follows the old approach). 

The default implementation theorically should just call existing 
LifecycleProvider stuff, and try to use createNewInstanceAndInject(String 
className) instead inject(...) as much as possible. The problem is there is a 
chance we need the inject(...) method, so it is better to include it since 
start.

Note CDI has something similar in order to work with the underlying web server, 
so one option is use that integration, but in some cases that's not true (for 
example if we are not in a JavaEE compliant server and CDI are added as a 
library, we also need to deal with that logic). 

I don't like very much the idea of provide a new spi InjectionLifecycleProvider 
to do "almost" the same as LifecycleProvider2, but in this case really we don't 
have choice. That's what we need to get it done right.


was (Author: lu4242):
There is a confusion behind how CDI affects JSF artifacts. To be clear, JSF 
artifacts are managed by JSF, not by CDI. Why? because in this case those 
objects does are not bound to an specific scope inside CDI, and there is no 
delegation of the instantiation process to CDI. 

In that sense, the existing rules related to CDI beans like hold the 
CreationalContext until destroy and so on does not apply. What we need here is 
implement these 3 steps:

- Injection
- invoke PostConstruct methods
- invoke PreDestroy methods

There is already an SPI interface for that in JSF called LifecycleProvider. The 
idea is we have an interface called LifecycleProvider2 with these methods:

Object newInstance(String className)
void postConstruct(Object o)
void destroyInstance(Object o)

This has worked well for a long time, and server vendors have usually a custom 
implementation of this interface. This is used to handle servlet 2.5 annotation 
in jsf managed beans (this is the clue left in JSF 2.2 spec section 5.4.1). 

Unfortunately, LifecycleProvider2 was an interface added to fix an issue and to 
avoid break things. As part of the cleanup for JSF 2.2 we need to provide a new 
SPI interface for this point. 

Taking into account the CDI InjectionTarget:

void    inject(T instance, CreationalContext<T> ctx) 
void    postConstruct(T instance) 
void    preDestroy(T instance) 

I would like to add the following spi interface:

public abstract class org.apache.myfaces.spi.InjectionLifecycleProvider
{
    public abstract Object createNewInstanceAndInject(String className) throws 
InjectionLifecycleProviderException;
    public abstract void inject(Object instance) throws 
InjectionLifecycleProviderException;
    public abstract void postConstruct(Object instance) throws 
InjectionLifecycleProviderException;
    public abstract void preDestroy(Object instance) throws 
InjectionLifecycleProviderException;
}

Other model to keep in mind is the one used by Mojarra for the same case:

public interface  InjectionProvider {
   public void inject(Object managedBean) throws InjectionProviderException;
   public void invokePreDestroy(Object managedBean) throws 
InjectionProviderException;
   public void invokePostConstruct(Object managedBean) throws 
InjectionProviderException;
}

Basically the diffence against the implementation in Mojarra is the use of an 
abstract class instead of a interface and the addition of a method 
createNewInstanceAndInject(String className), which most of the time comes in 
handy (and follows the old approach). 

The default implementation theorically should just call existing 
LifecycleProvider stuff, and try to use createNewInstanceAndInject(String 
className) instead inject(...) as much as possible. The problem is there is a 
chance we need the inject(...) method, so it is better to include it since 
start.

Note CDI has something similar in order to work with the underlying web server, 
so one option is use that integration, but in some cases that's not true (for 
example if we are not in a JavaEE compliant server and CDI are added as a 
library, we also need to deal with that logic). 

I don't like very much the idea of provide a new spi InjectionLifecycleProvider 
to do "almost" the same as LifecycleProvider2, but in this case really we don't 
have choice. That's what we need to get it done right.

> Web Container injection support should be provided for additional lifecycle 
> artifacts (not just managed beans)
> --------------------------------------------------------------------------------------------------------------
>
>                 Key: MYFACES-3786
>                 URL: https://issues.apache.org/jira/browse/MYFACES-3786
>             Project: MyFaces Core
>          Issue Type: Task
>          Components: JSR-344
>            Reporter: Leonardo Uribe
>            Assignee: Leonardo Uribe
>         Attachments: cdiELresolverWeb.zip, cdiELResolver.zip, 
> cdiPartialViewContext.war, cdiPartialViewContext.zip, cdi.patch, 
> cdiphaselistener1.patch, cdiphaselistener2.patch, cdiValidatorSource.zip, 
> cdiValidator.war
>
>
> This issue is all about how to inject beans into jsf artifacts.
> See JSF 2.2 section 5.4.1
> The problem here is in some point we need to give the control to the 
> underlying environment to inject beans into the artifacts, but we don't know 
> much about how to properly do it, so we need to try with examples.



--
This message was sent by Atlassian JIRA
(v6.1#6144)

Reply via email to