FYI, http://svn.apache.org/r1518703
Will be merging to branches shortly
Sergey
On 29/08/13 17:26, Sergey Beryozkin 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;
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
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
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com