myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Jencks <djen...@apache.org>
Subject Proposal for annotation processing
Date Mon, 12 Mar 2007 15:43:23 GMT
There's been a lot of discussion about annotation processing in a  
long thread http://www.nabble.com/%40PreDestroy%2C-Servlet-API%2C- 
tf3284592.html#a9136472
The current state of the code is that managed objects are created by  
MyFaces code, and then fed to an annotation processor using an  
interface like:

public interface AnnotationProcessor {
   public void postConstruct(Object instance);
   public void preDestroy(Object instance);
   public void processAnnotations(Object instance);
}

(Exceptions removed for clarity)

I have been implementing annotation support in the geronimo app  
client container and the geronimo-jetty6 integration and studying the  
openejb3 and native jetty annotation support and am starting to look  
at annotation support in a geronimo-myfaces integration, and have  
some ideas about how I'd like to handle geronimo injecting  
dependencies into jsf managed beans.

I'd like to propose that MyFaces use an interface like this for  
dealing with managed object construction, dependency injection, and  
lifecycle methods:

public interface LifecycleProvider {
     Object newInstance(String className);
     void destroyInstance(Object o);
}

This would fit in well with how annotation processing/dependency  
injection is done in the rest of geronimo.  It also would let the  
container in which MyFaces is running supply additional features such  
as supporting constructor dependency injection.

To go into what is probably blindingly obvious detail, this would be  
a MyFaces interface and the container in which MyFaces is running  
would supply an object implementing this interface for each application.

It's more or less trivial to write an adapter between this interface  
and the AnnotationProcessor interface currently in use, for  
integration with containers that want to supply an AnnotationProcessor.

So far I've thought of two issues, IMO one minor and the other  
requiring more thought (at least on my part :-).  Also I'm not at all  
familiar with the jsf spec so it's entirely possible I'm proposing  
details that can't be implemented.

1. The current code looks for ManagedBeanBuilder.NONE in between  
injecting dependencies and calling postConstruct.  I don't think this  
is appropriate: I think whatever is handling the annotations should  
know not to call postConstruct for this class.  If however the same  
class can be used in several different scopes the newInstance method  
could take the ManagedBean as parameter instead of the class name.

2. I'm proposing that the container inject an instance of  
LifecycleProvider for each jsf application.  This leads to the  
question, injects into what?  One simple possibility is a singleton  
LifecycleProviderFactory that indexes LifecycleProvider by  
application classloader.  However I wonder if there is a way to more  
directly inject the LifecycleProvider into the parts of MyFaces that  
actually need to use it rather than making these components go  
fishing for the one they need.  The kind of lazy initialization  
currently in wide use requires a lot more synchronization than it  
currently has to work reliably.  I would prefer to use constructor  
dependency injection to final fields to avoid this kind of problem.

I've opened a jira issue to hold code samples related to this  
proposal, and attached some initial implementations of these ideas  
for discussion.  Right now these new classes aren't hooked up to  
MyFaces, although I plan to work on that next.

Initial classes:

A      core/impl/src/main/java/org/apache/myfaces/config/annotation/ 
LifecycleProviderFactory.java
abstract class for singleton factory.

A      core/impl/src/main/java/org/apache/myfaces/config/annotation/ 
ApplicationIndexedLifecycleProviderFactory.java
  a LifecycleProviderFactory that expects to be populated by an  
external framework, with one LifecycleProvider instance per  
application classloader.

A      core/impl/src/main/java/org/apache/myfaces/config/annotation/ 
LifecycleProviderToAnnotationProcessorAdapter.java
an adapter between the LifecycleProvider implementation I'm proposing  
and the existing AnnotationProcessor interface currently in use.   
This basically relies on there being only one AnnotationProcessor  
shared between all applications.  This matches the current  
implementation but I think it is unsatisfactory in general.

A      core/impl/src/main/java/org/apache/myfaces/config/annotation/ 
LifecycleProvider.java
Proposed interface for MyFaces to plug in external services that  
handle annotations, object construction, etc.

A      core/impl/src/main/java/org/apache/myfaces/config/annotation/ 
AnnotationProcessorLifecycleProviderFactory.java
a LifecycleProviderFactory that uses the  
LifecycleProviderToAnnotationProcessorAdapter.

The jira issue is https://issues.apache.org/jira/browse/MYFACES-1559

Comments? Flames?

many thanks,
david jencks






Mime
View raw message