Mike Kienenberger wrote:
I've been reviewing open issues with my current application, and some
of them seem to deal with using Spring. This is kind of frustrating
because I'm finding that JSF managed beans do ALMOST everything I want
without Spring, except for providing a
InitializingBean.afterPropertiesSet() method call after a new bean's
properties have been set.
So after pondering it for a bit, it occurred to me that there's no
reason why support for this interface (repackaged for MyFaces) can't
be added to the org.apache.myfaces.el.VariableResolverImpl or to the
org.apache.myfaces.config.ManagedBeanBuilder class.
It seems to me that modifying one of the above classes to call the
below code would provide this functionality in a backward-compatible
way that does not affect the TCK.
if (newBean instanceof InitializingBean)
((InitializingBean)newBean).afterPropertiesSet();
This could be done either as the last line in
ManagedBeanBuilder.buildManagedBean() or right after the call to
buildManagedBean() in VariableResolverImpl.resolveVariable.
Unfortunately, I can't see a way to adding this functionality cleanly
as a generic JSF tomahawk extension, so it would have to remain a
MyFaces-only feature.
Thoughts?
Have you considered simply defining a managed property for your beans
that need initialisation?
<managed-property>
...
</managed-property>
<managed-property>
...
</managed-property>
<managed-property>
<description>initialiser called after properties set</description>
<property-name>initialised</property-name>
<value>true</value>
</managed-property>
public class MyManagedBean {
public void setInitialised(boolean dummy) {
// here we can do stuff required after all managed
// properties have been set on this bean
...
}
}
I haven't tested this, but don't see why it wouldn't work.
Managed properties are always initialised in the order they are
specified in the faces-config file in MyFaces, and with luck it's
actually part of the spec (haven't checked). So it's a *little* bit
hacky but not too bad.
This doesn't work for managed beans that use <map-entries> or
<list-entries> but those probably don't need post-initialisation anyway.
Re a general mechanism for post-init, that would be nice. However the
approach of having a class implement a special interface for lifecycle
stuff is going out of fashion, in favour of lifecycle annotations and
similar. So if anything was to be implemented I would rather see another
xml tag in the managed-bean specifying an initialisation method, or the
ManagedBeanManager checking for an annotation on the target class
(though that does require java 1.5). A possible xml extension would be:
<managed-bean>
<t:post-init xmlns:t="http://myfaces.apache.org/..." method="init"/>
I haven't checked whether the schema for faces-config.xml is "open" with
respect to elements in foreign namespaces or not; if not that would be a
nice addition.
Regards,
Simon