On Thu, Aug 29, 2013 at 6:26 PM, Sergey Beryozkin <[email protected]> wrote:
> Hi
>
> On 29/08/13 14:45, Thibaut Robert wrote:
>>
>> On Thu, Aug 29, 2013 at 2:36 PM, Sergey Beryozkin <[email protected]>
>> 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) .
If you want to be exhaustive, I think there are 3 interesting cases:
- always call the methods (current behavior, not possible in your commit)
- only call pre-destroy for prototype (future default behavior)
- never call them

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

> 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.
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
>>>>> <[email protected]> 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
>
>

Reply via email to