|
From: <jue...@we...> - 2004-01-10 17:29:55
|
Colin, all,
=20
I've just implemented support for before- and after-initialization =
post-processors: The BeanPostProcessor interface has a new "boolean =
applyBeforeInitialization" method now, returning true for example in =
ApplicationContextAwareProcessor but false in AbstractAutoProxyCreator. =
BeanNameAware and BeanFactoryAware are also satisfied *before* =
initialization of the bean.
=20
In total, this gives the following initialization order for a bean now:
1. setBeanName
2. setBeanFactory
3. setApplicationContext (only in a context, obviously)
4. custom before-initialization BeanPostProcessors
5. afterPropertiesSet / init-method
6. custom after-initialization BeanPostProcessors
=20
I'll adapt the Javadocs accordingly.
=20
Juergen
=20
________________________________
Von: spr...@li... im Auftrag =
von Colin Sampaleanu
Gesendet: Mi 07.01.2004 14:09
An: spr...@li...
Betreff: Re: [Springframework-developer] Rationale for =
setApplicationContext() coming after afterPropertiesSet()
I was originally thinking of two marker interfaces for the initializing
and post initializing BeanPostProcessors (as per a traditional listener
design), but having two methods would also work fine...
W/regards to the initializing one being allowed to return a wrapped
instance of the bean, I am not sure there is anything really wrong with
that. The distinction after all betwen the post processor types is for
the most part on wether they come before or after the 'officially
initialized' demarcation point (InitializingBean), and as such whether
or not the post processor can expect a fully initialized bean, and
whether the bean can expect at the dermarcation point that it is fully
initialized. The fact that a post processor can wrap the bean before or
after doesn't really change much...
j=FCrgen h=F6ller [werk3AT] wrote:
>Colin,
>
>You've got a point here. The current invocation order is a result of =
context implementation issues rather than design from the user =
perspective. I guess we won't have to worry about backward compatibility =
too much: After all, we discourage everyone to implement =
BeanFactoryAware of ApplicationContextAware for typical beans. With the =
new core.io.Resource stuff in M4, there's even one less reason to =
implement the latter.
>
>So let's design this in a clean and obvious manner for RC1. Your first =
suggestion sounds good to me: However, we would need to introduce a =
distinction between "initializing" BeanPostProcessors and =
"post-initializing" ones. This could happen via a marker sub-interface, =
for example, or via a new method in the interface.
>
>A special issue is that a BeanPostProcessor can return a wrapped =
instance of the bean: This isn't really desirable for "initializing" =
BeanPostProcessors, is it? So maybe we'd even need to introduce a =
separate interface that just allows processing of the given bean =
instance. Any thoughts?
>
>Juergen
>
>
>________________________________
>
>Von: spr...@li... im Auftrag =
von Colin Sampaleanu
>Gesendet: Mi 07.01.2004 05:54
>An: spr...@li...
>Betreff: Re: [Springframework-developer] Rationale for =
setApplicationContext() coming after afterPropertiesSet()
>
>
>
>I was hoping for some more discussion on this, but it looks like nobody
>bit...
>
>In the meantime, I have clarified the existing ordering of the =
lifecycle
>methods in the JavaDocs for InitializingBean, BeanFactoryAware, and
>ApplcationContextAware.
>
>I still think there somewhat of a (big) hole with regards to the =
current
>initializing method handling. Currently, BeanPostProcessors are all
>applied _after_ ApplicationContextAware (although this order is not
>documented). This works for any BeanPostProcessors which expect to be
>given fully initialized beans, as they will be given a bean initialized
>fully (and knowing it) due to use of afterPropertiesSet
>(InitializingBean), setBeanFactory (BeanFactoryAware), or
>setApplicationContext (ApplicationContextAware). However, if somebody
>needs to apply a BeanPostProcessor to set some properties of a bean as
>part of the initialization, there is _no_ reliable mechanism to call an
>init method on the bean afterwards; neither via an entry in the XML =
def,
>nor via a marker interface.
>
>What makes the most sense to _me_ is to have the following sequence =
apply:
>- BeanFactoryAware, ApplicationContextAware, a set of 'initializing'
>BeanPostProcessors, InitializingBean, and finally a another set of
>'post-initializing' BeanPostProcessors.
>
>This obviously has implications in terms of backwards compatibility
>since InitializingBean applies in a different sequence. A solution =
which
>would be completely backwards compatible (but I think less obvious),
>would be to do
>- InitializingBean, BeanFactoryAware, 'initializing' =
BeanPostProcessors,
>ApplicationContextAware, 'post-initializing' BeanPostProcessors. People
>could in this case use any of the three marker interfaces to =
initialize,
>as suitable...
>
>Any comments?
>
>Regards,
>Colin
>
>Colin Sampaleanu wrote:
>
>=20
>
>>I think any distinction between 'basic JavaBean stuff' and
>>'application context stuff' is often going to be artificial. If you
>>think about some class that actually needs the context, it is probably
>>going to use it in a similar fashion to any other property inside it.
>>
>>But the initialize method (or the specific instance
>>afterPropertiesSet) is also a lifecycle method, and it is in the wrong
>>order as far as _any_ BeanPostProcessors are concerned, including
>>ApplicationContextAware. Right now there is no mechanism to specify
>>that an init method should be called after everything has been done to
>>it by the context, including post processors. You can't even rely on
>>setApplicationContext() as your init method because in fact some
>>post-processors may act after it.
>>
>>If you think about it, you should be able to take a working
>>beanfactory, with working beans, and if you need something special
>>from the application context (like the post-processors, or indirectly,
>>via the fact that one of its dependencies needs the application
>>context) just switch to using the same setup in an application
>>context. You can't really do that if you can no longer rely on the
>>original init methods from when you were in the bean factory.
>>
>>So for sure I think there is a need for the ability to call an init
>>method once post-processing is done, and I can't see the justification
>>for making this different than the existing beanfactory init =
mechanism...
>>
>>Regards,
>>Colin
>>
>>Rod Johnson wrote:
>>
>> =20
>>
>>>Colin,
>>>
>>>I like the present order: not surprisingly, perhaps, as I chose it. =
The
>>>rationale is: get the basic JavaBean stuff in order first, then do =
any
>>>application context stuff.
>>>
>>>Certainly the docs should be consistent.
>>>
>>>Now at least I understand the confusion: setApplicationContext() is =
not
>>>treated as a normal JavaBean property, but as a lifecycle method.
>>>Perhaps
>>>the "set" prefix was unwise.
>>>
>>>Regards,
>>>Rod
>>>
>>>----- Original Message ----- From: "Colin Sampaleanu"
>>><col...@ex...>
>>>To: <spr...@li...>
>>>Sent: Monday, January 05, 2004 8:35 PM
>>>Subject: [Springframework-developer] Rationale for
>>>setApplicationContext()
>>>coming after afterPropertiesSet()
>>>
>>>
>>>I've had a couple of discussions now with people where I've tried to
>>>explain why setApplicationContext comes after afterPropertiesSet (and
>>>after any custom initializing method you define), and frankly, I =
think
>>>it just doesn't make sense except for the fact that it's that way
>>>right now.
>>>
>>>Most beans should of course not be using the application context, but =
if
>>>they need it, people are not going to understand the rationale as to =
why
>>>that property is set after the initializing method is called, and =
that
>>>they must instead treat setApplicationContext itself as an =
initializer
>>>method.
>>>
>>>I don't know if anybody thinks it's worth changing the order, but if
>>>not, this thing is going to hit new users on the head on a regular
>>>basis... At a minimum, if no code is changed, we need to update the
>>>JavaDoc for ApplicationContextAware to explain the order. I can do
>>>that...
>>>
>>>Regards,
>>>Colin
>>>
>>>j=FCrgen h=F6ller [werk3AT] wrote:
>>>
>>>
>>>
>>> =20
>>>
>>>>Actually, this is intended behavior, although it may be debatable
>>>>whether
>>>>
>>>> =20
>>>>
>>>it is appropriate. setApplicationContext is not really meant to be
>>>combined
>>>with an init-method. The latter is for non-Spring-aware beans, while =
the
>>>former is the strongest dependency a bean can have on Spring. You =
should
>>>*not* design your beans to depend on that initialization order.
>>>
>>>
>>> =20
>>>
>>>>As a solution, you could put your initialization code in your
>>>>
>>>> =20
>>>>
>>>setApplicationContext implementation, or in an =
initApplicationContext()
>>>method that gets triggered by setApplicationContext. Have a look at =
the
>>>ApplicationObjectSupport convenience base class, it provides such a
>>>method
>>>out of the box. Of course, extending ApplicationObjectSupport is not =
an
>>>option if you already have a different natural base class.
>>>
>>>
>>> =20
>>>
>>>>Juergen
>>>>
>>>>
>>>>-----Original Message-----
>>>>From: Keith Donald [mailto:kd...@cs...]
>>>>Sent: Thursday, October 30, 2003 4:22 PM
>>>>To: spr...@li...
>>>>Subject: RE: [Springframework-user] setApplicationContext not being
>>>>called
>>>>
>>>>
>>>>Juergen,
>>>>
>>>>Wanted to update you on this issue post M2. setApplicationContext
>>>>is being
>>>>
>>>> =20
>>>>
>>>called now on all my ApplicationContextAware beans, thanks. The only
>>>issue
>>>I have remaining is it seems the bean init-method method
>>>("initialize()" in
>>>my case) is called by the container before setApplicationContext. My
>>>initialize() method does stuff that requires the context - for
>>>example, it
>>>looks up messages for initializing view components. So I would
>>>really need
>>>setApplicationContext() called before initialize() to prevent
>>>NullPointerExceptions.
>>>
>>>
>>> =20
>>>
>>>>Thanks,
>>>>Keith
>>>>
>>>>2003-10-30 10:16:58,099 DEBUG =
[com.csi.cogids.console.QueryNavigator] -
>>>>
>>>> =20
>>>>
>>><initialize called>
>>>
>>>
>>> =20
>>>
>>>>2003-10-30 10:16:58,193 DEBUG
>>>>[com.csi.cogids.console.qQueryNavigator] -
>>>>
>>>> =20
>>>>
>>><setApplicationContext called>
>>>
>>>
>>> =20
>>>
>>>>Keith Donald
>>>>Senior Software Engineer
>>>>kd...@cs...
>>>>321-676-2923 x403
>>>>
>>>>
>>>>
>>>>
>>>>-----Original Message-----
>>>>From: spr...@li...
>>>>
>>>> =20
>>>>
>>>[mailto:spr...@li...] On Behalf =
Of
>>>j=FCrgen h=F6ller [werk3AT]
>>>
>>>
>>> =20
>>>
>>>>Sent: Thursday, October 23, 2003 2:14 AM
>>>>To: spr...@li...
>>>>Subject: Re: [Springframework-user] setApplicationContext not being
>>>>called
>>>>
>>>>
>>>>Keith,
>>>>
>>>>This was caused by the fact that ApplicationContextAware was being
>>>>
>>>> =20
>>>>
>>>processed after the underlying bean factory finished its work, on
>>>demand in
>>>getBean calls to the application context. I've completely reworked
>>>this for
>>>1.0 M2; now, the bean factory has a BeanPostProcessor hook that is =
also
>>>internally used for processing ApplicationContextAware beans, to be
>>>applied
>>>when the underlying bean factory creates any kind of bean.
>>>
>>>
>>> =20
>>>
>>>>So as of 1.0 M2, to be released tomorrow, this should work properly
>>>>in all
>>>>
>>>> =20
>>>>
>>>cases. If there should be any remaining issues, please report them
>>>against
>>>1.0 M2. If you're eager, you can also try a CVS snapshot today.
>>>
>>>
>>> =20
>>>
>>>>Juergen
>>>>
>>>>
>>>>
>>>>-----Urspr=FCngliche Nachricht----- Von: Keith Donald
>>>>[mailto:kd...@cs...]
>>>>Gesendet: Di 21.10.2003 19:50
>>>>An: spr...@li...
>>>>Cc:
>>>>Betreff: [Springframework-user] setApplicationContext not being =
called
>>>>
>>>>
>>>>
>>>>Forgive me if this issue has already been addressd. It appears
>>>>setApplicationContext(ApplicationContext) is not being called on my
>>>>ApplicationContextAware prototype beans that are not directly
>>>>instantiated
>>>>by a call to beanFactory.getBean(beanName), but rather are wired
>>>>"child"
>>>>beans instantiated as a result of a <bean ref> references from a =
parent
>>>>prototype.
>>>>
>>>>To give you an example of what I mean:
>>>>
>>>> // parent prototype
>>>> <bean id=3D"sessionVisualizerPage"
>>>> =
class=3D"com.csi.cogids.console.SessionVisualizerPage"
>>>> singleton=3D"false">
>>>> <property name=3D"queryNavigator"><ref
>>>>bean=3D"queryNavigator"/></property>
>>>> </bean>
>>>>
>>>> // child prototype
>>>> <bean id=3D"queryNavigator"
>>>> class=3D"com.csi.cogids.console.query.QueryNavigator"
>>>> singleton=3D"false"
>>>> init-method=3D"initialize">
>>>> <property name=3D"newQueryAction"><ref
>>>>bean=3D"newQueryAction"/></property>
>>>> <property name=3D"newGroupAction"><ref
>>>>bean=3D"newGroupAction"/></property>
>>>> </bean>
>>>>
>>>>A sessionVisualizerPage prototype gets instantiated when the page is
>>>>
>>>> =20
>>>>
>>>loaded
>>>
>>>
>>> =20
>>>
>>>>in my application. The queryNavigator prototype also gets =
instantiated
>>>>because of the <bean ref>. setApplicationContext() IS called on
>>>>sessionVisualizerPage, but not on QueryNavigator, even though both =
are
>>>>ApplicationContextAware for message lookups.
>>>>
>>>>Thanks,
>>>>Keith
>>>>
>>>>Keith Donald
>>>>Senior Software Engineer
>>>>kd...@cs...
>>>>321-676-2923 x403
>>>>=20
>>>> =20
>>>>
-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills. Sign up for =
IBM's
Free Linux Tutorials. Learn everything from the bash shell to sys =
admin.
Click now! http://ads.osdn.com/?ad_id=3D1278&alloc_id=3D3371&op=3Dclick
_______________________________________________
Springframework-developer mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-developer
|