cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: Jax-RS SpringResourceFactory and lifecycle methods
Date Fri, 30 Aug 2013 10:15:22 GMT
Hi
On 30/08/13 10:58, Thibaut Robert wrote:
> On Thu, Aug 29, 2013 at 6:26 PM, Sergey Beryozkin <sberyozkin@gmail.com> wrote:
>> Hi
>>
>> On 29/08/13 14:45, Thibaut Robert wrote:
>>>
>>> On Thu, Aug 29, 2013 at 2:36 PM, Sergey Beryozkin <sberyozkin@gmail.com>
>>> wrote:
>>>>
>>>> Hi, actually, Spring is not calling lifecycle methods when prototype
>>>> scope
>>>> beans are used, directly or when wrapped in SpringResourceFactory. I've
>>>> only
>>>> managed to confirm it is calling these methods for singletons (if not
>>>> wrapped in this factory) or per-request beans.
>>>
>>> Strange, I don't see the same behovior:
>>> - for prototype, spring calls the postConstruct methods. It never
>>> calls the predestroy (because it doesn't know when to do so).
>>> - for singleton, spring calls the postConstruct too at application
>>> startup, even when wrapped in SpringResourceFactory
>>> I use spring 3.1.2 btw.
>>>
>>>> I think we need to keep the current behavior enabled by default, and I'm
>>>> adding a 'callLifecylceMethods' boolean property to disable it if
>>>> preferred:
>>>> the only issue here is that in order to disable it one has to directly
>>>> configure SpringResourceFactory which is not as convenient as simply
>>>> listing
>>>> the bean names, but I'm getting concerned I may break someone's code if I
>>>> disable SpringResourceFactory calling the lifecycle methods by default
>>>
>>> I don't share this opinion, but I can handle the burden of having to
>>> declare the SpringResourceFactory. I understand well the compatibility
>>> concern too.
>>
>>
>> I've found what the problem was in my tests, apparently putting
>> PostConstruct and PreDestroy annotations on interface is not really valid in
>> Spring, so after I pushed them down to the abstract class I started seeing
>> prototype beans post-constructed too.
>>
>>
>>>
>>>> If you know how to get prototype beans called their lifecycle methods
>>>> then
>>>> let me know please, I would not then worry about a case where we have
>>>> regular singletons wrapped in the factory because no practical reason for
>>>> doing it exists I guess,
>>>
>>>
>>> For me the only arguable case is whether to call postdestroy after the
>>> request for prototype beans. Doing so makes sense for me. Spring doc
>>> says: All lifecycle management past that point [the bean creation]
>>> must be handled by the client.
>>>
>>> (http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-factory-scopes-prototype)
>>> I am still a little hesitant because it will not work for a
>>> post-destroy method declared in xml fashion, but it's an acceptable
>>> limitation I think.
>>>
>>> In all other cases, spring should call the methods for us.
>>
>>
>> OK, here is what I've done:  I removed a "callLifecycleMethods" property
>> introduced with my last commit an hour or so ago and
>>
>> - added "callPostConstruct" (default is false), unless a user enables it the
>> factory won't call PostConstruct
>>
>> - added "callPreDestroy" - default is true, but it is only effective if the
>> bean has a prototype scope. So Pre-Destroy will only be called by the
>> factory if it is a prototype bean, but the user can still disable it if
>> preferred by setting "callPreDestroy" to false
>>
>> That should work OK; if you have some concerns or more ideas on how to
>> improve it let me know please;
>
> Ok, I don't want to be nitpicknig but you asked me, then : I'm fine
> with the default behavior in this solution. However, I'm a bit
> concerned that a user can force post-construct to be called, but he
> can't force predestroy to called (unless scope is protoype) .

Well, I've thought about it and in fact my tests confirm that Spring 
calls preDestroy for Spring request scope beans and also for singletons 
once the test server goes down.
Obviously if it is a prototype, and Spring allocates a new instance 
every time then we need to pre-destroy it.

Also note that I've updated it a code a bit and if we have a case where 
pre-destroy has to be called then Custom factory will override a check 
method returning boolean and force it.


> If you want to be exhaustive, I think there are 3 interesting cases:
> - always call the methods (current behavior, not possible in your commit)
This is what we moved away from. Why would we want to keep a code which 
results in duplicate post construct and pre-destroy calls ?
> - only call pre-destroy for prototype (future default behavior)

You right in that it is only a default - if we have a case with the 
non-prototype beans requiring a post-destroy then a trivial override 
will do it :-). I guess we can't write a code which will work correctly 
for all type of scopes possibly supported by Spring

> - never call them
>
this is nearly what we do now, by default, with the only exceptions 
being the prototypes but this can be disabled :-)

> But I'm just wandering if these options will be used ... I'm sure you
> have more important stuff to work on :)
>

What we do most of the time is fixing a lot of issues which kinf of 
minor but of course the sum of all the fixes makes a difference :-)

>> I've also spotted that unless an endpoint is specifically configured,
>> PreDestroy will be called twice. The contextual property,
>> "org.apache.cxf.service.scope", set to "request" (a bit misnamed, do not
>> remember why I named it this way) can be used to postpone calling
>> PostDestroy until the response has been serialized, apparently it can help
>> in dealing with some complex JAXB hierarchies, etc, but at the moment if
>> this property is not set and PreDestroy is there then it will be called
>> twice, fixing it too.
>>
>> Finally, added the ability to customize the names of init/destroy methods in
>> the factory
>>
>> Thanks, Sergey
>
> Thanks for this discussion and your responsiveness.

No problems, thanks for your feedback

Cheers, Sergey

> Cheers ;)
> Thibaut
>
>>
>>>
>>> Thibaut
>>>
>>>> Cheers, Sergey
>>>>
>>>>
>>>>
>>>> On 29/08/13 12:04, Sergey Beryozkin wrote:
>>>>>
>>>>>
>>>>> On 29/08/13 11:33, Thibaut Robert wrote:
>>>>>>
>>>>>>
>>>>>> On Wed, Aug 28, 2013 at 5:24 PM, Sergey Beryozkin
>>>>>> <sberyozkin@gmail.com> wrote:
>>>>>>>
>>>>>>>
>>>>>>> Hi
>>>>>>>
>>>>>>> On 28/08/13 10:44, Thibaut Robert wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> I have some jax-rs service beans deployed via Spring. I use
the
>>>>>>>> jaxrs:server tag with the beanNames attribute to specify
my bean. My
>>>>>>>> beans are in a custom spring scope.
>>>>>>>>
>>>>>>>> Everything works fine, except that I notice that both Spring
and cxf
>>>>>>>> calls my @PostConstruct and @PreDestroy methods. I think
this is a
>>>>>>>> bit
>>>>>>>> confusing. As cxf SpringResourceFactory delegate the resource
>>>>>>>> lifecycle to spring, why is it calling itself the lifecycle
methods ?
>>>>>>>>
>>>>>>>> In my case, the @Postconstruct is called twice at the first
request
>>>>>>>> (by spring then cxf). Then once per request (by cxf), whereas
it is
>>>>>>>> using an already existing instance. I would prefer cxf doesn't
call
>>>>>>>> the methods at all.
>>>>>>>>
>>>>>>> I think I added it in a 'copy-and-paste' kind of fashion, the
runtime
>>>>>>> would
>>>>>>> release a current service instance and if it is a per-request
instance
>>>>>>> explicitly managed by the runtime then it makes sense, but I
can see
>>>>>>> now it
>>>>>>> may cause side-effects, I'll make SpringResourceFactory calling
>>>>>>> lifecycle
>>>>>>> methods only if requested by the user, in meantime, the workaround
is
>>>>>>> to
>>>>>>> register a custom SpringResourceFactory which will ignore release
>>>>>>> calls
>>>>>>
>>>>>>
>>>>>>
>>>>>> I am just wondering if there is a use case where calling the lifecycle
>>>>>> method is usefull. Even a per request instance, if you put it in
>>>>>> request scope, the methods will be called by spring. Maybe if you
use
>>>>>> prototype scope ? But in my view, the lifecycle has to be managed
by
>>>>>> the container owning the bean, which is always spring with this
>>>>>> factory.
>>>>>
>>>>>
>>>>>
>>>>> You are right, I've played a bit and see Spring factory duplicating what
>>>>> Spring does too, so I will disable it by default, will keep an optional
>>>>> flag there just in case
>>>>>
>>>>>>
>>>>>> For the moment I will either use your workaround, or declare my
>>>>>> lifecycle methods in my spring xml file.
>>>>>
>>>>>
>>>>>
>>>>> Sure, the latter option can be even simpler, at the moment it is not
>>>>> easy to block the post construct call, will fix that too
>>>>>
>>>>> Thanks, Sergey
>>>>>
>>>>>
>>>>>>
>>>>>> Thanks for kind support!
>>>>>> Thibaut
>>>>>>
>>>>>>> Cheers, Sergey
>>>>>>>
>>>>>>>> Regards,
>>>>>>>> Thibaut
>>>>>>>>
>>>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Sergey Beryozkin
>>>>
>>>> Talend Community Coders
>>>> http://coders.talend.com/
>>>>
>>>> Blog: http://sberyozkin.blogspot.com
>>
>>


Mime
View raw message