|
From: <jue...@we...> - 2004-01-07 07:29:46
|
Colin,
=20
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.
=20
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.
=20
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?
=20
Juergen
=20
________________________________
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:
> 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:
>
>> 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
>>
-------------------------------------------------------
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
|