Hi
On 30/08/13 10:58, Thibaut Robert wrote:
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) .
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
<[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