On Fri, Aug 30, 2013 at 12:15 PM, Sergey Beryozkin <[email protected]> wrote: > 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 ? I mentioned it because you include a callPostConstruct option - to restore old beahvior I suppose. When the option is true it should always call preDestroy . But I don't understand this is the case.
>> - 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 >>> >>> >>> >
