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 > >
