You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by "CRANFORD, CHRIS" <Ch...@setech.com> on 2015/10/15 06:57:40 UTC

Spring BeanPostProcessor called twice for Struts managed beans

In a recent BeanPostProcessor implementation, I noticed our logic was being invoked twice in both the before and after initialization callbacks for struts constructed objects like actions, interceptors, etc while normal constructed Spring beans via component scanning were only being invoked once.

After debugging in 3.2.24.1, I narrowed the issue down to the SpringObjectFactory implementation in Xwork2 at lines 194 to 197.  It seems XWork's implementation manually calls the before and after BeanPostProcessor callbacks.  Looking at the Spring source for AbstractAutowireCapableBeanFactory, it seems initializeBean's implementation also calls these callback methods too, which is what leads to re-evaluating the struts constructed objects twice.

I believe the plugin is based on Spring 3.0.5 (IIRC) and even reviewing the code base at that release along with the latest 4.2.1 release, both confirm that initializeBean has always invoked the BeanPostProcessor callbacks internally and therefore, XWork's implementation really should not worry with manually invoking them too.

Is there a technical reason why the SpringObjectFactory is doing this or is this an oversight?  
This just seems like a significant overhead on bean management that could be avoided, right?

Thanks,
Chris


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


RE: Spring BeanPostProcessor called twice for Struts managed beans

Posted by Martin Gainty <mg...@hotmail.com>.



> From: Chris.Cranford@setech.com
> To: user@struts.apache.org
> Subject: RE: Spring BeanPostProcessor called twice for Struts managed beans
> Date: Thu, 15 Oct 2015 13:26:01 +0000
> 
> I could be mistaken, but that would only solve not invoking the post instantiation callbacks on the bean and would also imply that the BeanPostProcessor implementations actually implement the InstantiationAwareBeanPostProcessor interface I believe.   It also seems far more logical to put this burn on the dependency injection framework itself, particularly since the framework already manages this bean lifecycle workflow itself.  

MG>how would DI lifecycle framework detect "This Spring bean has already been initialised"?
MG>if we can guarantee synchronised access to the initialised bean perhaps some manner of registration such as MG>SingletonBeanRegistry.registerSingleton(
MG>http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/config/SingletonBeanRegistry.html#registerSingleton-java.lang.String-java.lang.Object-
MG>afterward we detect "has this initialised bean already been registered" with getSingleton(String beanName)
MG>WDYT?
> 
> -----Original Message-----
> From: Martin Gainty [mailto:mgainty@hotmail.com] 
> Sent: Thursday, October 15, 2015 7:29 AM
> To: Struts Users Mailing List <us...@struts.apache.org>
> Subject: RE: Spring BeanPostProcessor called twice for Struts managed beans
> 
> > From: lukaszlenart@apache.org
> > Date: Thu, 15 Oct 2015 07:56:24 +0200
> > Subject: Re: Spring BeanPostProcessor called twice for Struts managed 
> > beans
> > To: user@struts.apache.org
> > 
> > You are probably right :) Please register an issue and target 2.3.25 
> > as a fix version.
> > 
> > 
> > Regards
> > --
> > Łukasz
> > + 48 606 323 122 http://www.lenart.org.pl/
> > 
> > 2015-10-15 6:57 GMT+02:00 CRANFORD, CHRIS <Ch...@setech.com>:
> > > In a recent BeanPostProcessor implementation, I noticed our logic was being invoked twice in both the before and after initialization callbacks for struts constructed objects like actions, interceptors, etc while normal constructed Spring beans via component scanning were only being invoked once.
> > >
> > > After debugging in 3.2.24.1, I narrowed the issue down to the SpringObjectFactory implementation in Xwork2 at lines 194 to 197.  It seems XWork's implementation manually calls the before and after BeanPostProcessor callbacks.  Looking at the Spring source for AbstractAutowireCapableBeanFactory, it seems initializeBean's implementation also calls these callback methods too, which is what leads to re-evaluating the struts constructed objects twice.
> > >
> > > I believe the plugin is based on Spring 3.0.5 (IIRC) and even reviewing the code base at that release along with the latest 4.2.1 release, both confirm that initializeBean has always invoked the BeanPostProcessor callbacks internally and therefore, XWork's implementation really should not worry with manually invoking them too.
> > >
> > > Is there a technical reason why the SpringObjectFactory is doing this or is this an oversight?
> > > This just seems like a significant overhead on bean management that could be avoided, right?
> > >
> > > Thanks,
> > > Chris
> MG>2 leads who preceeded Lukasz didnt test out the 
> MG>alwaysRespectAutowireStrategy = false logic no testcase means bug 
> MG>buried deep within code and  never shouldve seen light of day in a 
> MG>Continous Integration environment all features have at least one 
> MG>testcase..so if juergens spring code detects property assignment on a 
> MG>bean has already been set..maybe we can catch detect that
> /**
>      * Perform operations after the bean has been instantiated, via a constructor or factory method,
>      * but before Spring property population (from explicit properties or autowiring) occurs.
>      * <p>This is the ideal callback for performing field injection on the given bean instance.
>      * See Spring's own {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor}
>      * for a typical example.
>      * @param bean the bean instance created, with properties not having been set yet
>      * @param beanName the name of the bean
>      * @return {@code true} if properties should be set on the bean; {@code false}
>      * if property population should be skipped. Normal implementations should return {@code true}.
>      * Returning {@code false} will also prevent any subsequent InstantiationAwareBeanPostProcessor
>      * instances being invoked on this bean instance.
>      * @throws org.springframework.beans.BeansException in case of errors
>      */
>     boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
> MG>Good Catch Chris!
> > >
> > >
> > > --------------------------------------------------------------------
> > > - To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> > > For additional commands, e-mail: user-help@struts.apache.org
> > >
> > 
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> > For additional commands, e-mail: user-help@struts.apache.org
> > 
>  		 	   		  
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 
 		 	   		  

RE: Spring BeanPostProcessor called twice for Struts managed beans

Posted by "CRANFORD, CHRIS" <Ch...@setech.com>.
I could be mistaken, but that would only solve not invoking the post instantiation callbacks on the bean and would also imply that the BeanPostProcessor implementations actually implement the InstantiationAwareBeanPostProcessor interface I believe.   It also seems far more logical to put this burn on the dependency injection framework itself, particularly since the framework already manages this bean lifecycle workflow itself.  

-----Original Message-----
From: Martin Gainty [mailto:mgainty@hotmail.com] 
Sent: Thursday, October 15, 2015 7:29 AM
To: Struts Users Mailing List <us...@struts.apache.org>
Subject: RE: Spring BeanPostProcessor called twice for Struts managed beans

> From: lukaszlenart@apache.org
> Date: Thu, 15 Oct 2015 07:56:24 +0200
> Subject: Re: Spring BeanPostProcessor called twice for Struts managed 
> beans
> To: user@struts.apache.org
> 
> You are probably right :) Please register an issue and target 2.3.25 
> as a fix version.
> 
> 
> Regards
> --
> Łukasz
> + 48 606 323 122 http://www.lenart.org.pl/
> 
> 2015-10-15 6:57 GMT+02:00 CRANFORD, CHRIS <Ch...@setech.com>:
> > In a recent BeanPostProcessor implementation, I noticed our logic was being invoked twice in both the before and after initialization callbacks for struts constructed objects like actions, interceptors, etc while normal constructed Spring beans via component scanning were only being invoked once.
> >
> > After debugging in 3.2.24.1, I narrowed the issue down to the SpringObjectFactory implementation in Xwork2 at lines 194 to 197.  It seems XWork's implementation manually calls the before and after BeanPostProcessor callbacks.  Looking at the Spring source for AbstractAutowireCapableBeanFactory, it seems initializeBean's implementation also calls these callback methods too, which is what leads to re-evaluating the struts constructed objects twice.
> >
> > I believe the plugin is based on Spring 3.0.5 (IIRC) and even reviewing the code base at that release along with the latest 4.2.1 release, both confirm that initializeBean has always invoked the BeanPostProcessor callbacks internally and therefore, XWork's implementation really should not worry with manually invoking them too.
> >
> > Is there a technical reason why the SpringObjectFactory is doing this or is this an oversight?
> > This just seems like a significant overhead on bean management that could be avoided, right?
> >
> > Thanks,
> > Chris
MG>2 leads who preceeded Lukasz didnt test out the 
MG>alwaysRespectAutowireStrategy = false logic no testcase means bug 
MG>buried deep within code and  never shouldve seen light of day in a 
MG>Continous Integration environment all features have at least one 
MG>testcase..so if juergens spring code detects property assignment on a 
MG>bean has already been set..maybe we can catch detect that
/**
     * Perform operations after the bean has been instantiated, via a constructor or factory method,
     * but before Spring property population (from explicit properties or autowiring) occurs.
     * <p>This is the ideal callback for performing field injection on the given bean instance.
     * See Spring's own {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor}
     * for a typical example.
     * @param bean the bean instance created, with properties not having been set yet
     * @param beanName the name of the bean
     * @return {@code true} if properties should be set on the bean; {@code false}
     * if property population should be skipped. Normal implementations should return {@code true}.
     * Returning {@code false} will also prevent any subsequent InstantiationAwareBeanPostProcessor
     * instances being invoked on this bean instance.
     * @throws org.springframework.beans.BeansException in case of errors
     */
    boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
MG>Good Catch Chris!
> >
> >
> > --------------------------------------------------------------------
> > - To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> > For additional commands, e-mail: user-help@struts.apache.org
> >
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 
 		 	   		  


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


RE: Spring BeanPostProcessor called twice for Struts managed beans

Posted by Martin Gainty <mg...@hotmail.com>.


> From: lukaszlenart@apache.org
> Date: Thu, 15 Oct 2015 07:56:24 +0200
> Subject: Re: Spring BeanPostProcessor called twice for Struts managed beans
> To: user@struts.apache.org
> 
> You are probably right :) Please register an issue and target 2.3.25
> as a fix version.
> 
> 
> Regards
> -- 
> Łukasz
> + 48 606 323 122 http://www.lenart.org.pl/
> 
> 2015-10-15 6:57 GMT+02:00 CRANFORD, CHRIS <Ch...@setech.com>:
> > In a recent BeanPostProcessor implementation, I noticed our logic was being invoked twice in both the before and after initialization callbacks for struts constructed objects like actions, interceptors, etc while normal constructed Spring beans via component scanning were only being invoked once.
> >
> > After debugging in 3.2.24.1, I narrowed the issue down to the SpringObjectFactory implementation in Xwork2 at lines 194 to 197.  It seems XWork's implementation manually calls the before and after BeanPostProcessor callbacks.  Looking at the Spring source for AbstractAutowireCapableBeanFactory, it seems initializeBean's implementation also calls these callback methods too, which is what leads to re-evaluating the struts constructed objects twice.
> >
> > I believe the plugin is based on Spring 3.0.5 (IIRC) and even reviewing the code base at that release along with the latest 4.2.1 release, both confirm that initializeBean has always invoked the BeanPostProcessor callbacks internally and therefore, XWork's implementation really should not worry with manually invoking them too.
> >
> > Is there a technical reason why the SpringObjectFactory is doing this or is this an oversight?
> > This just seems like a significant overhead on bean management that could be avoided, right?
> >
> > Thanks,
> > Chris
MG>2 leads who preceeded Lukasz didnt test out the alwaysRespectAutowireStrategy = false logic
MG>no testcase means bug buried deep within code and  never shouldve seen light of day in a Continous Integration environment
MG>all features have at least one testcase..so
MG>if juergens spring code detects property assignment on a bean has already been set..maybe we can catch detect that 
/**
     * Perform operations after the bean has been instantiated, via a constructor or factory method,
     * but before Spring property population (from explicit properties or autowiring) occurs.
     * <p>This is the ideal callback for performing field injection on the given bean instance.
     * See Spring's own {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor}
     * for a typical example.
     * @param bean the bean instance created, with properties not having been set yet
     * @param beanName the name of the bean
     * @return {@code true} if properties should be set on the bean; {@code false}
     * if property population should be skipped. Normal implementations should return {@code true}.
     * Returning {@code false} will also prevent any subsequent InstantiationAwareBeanPostProcessor
     * instances being invoked on this bean instance.
     * @throws org.springframework.beans.BeansException in case of errors
     */
    boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
MG>Good Catch Chris!
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> > For additional commands, e-mail: user-help@struts.apache.org
> >
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 
 		 	   		  

Re: Spring BeanPostProcessor called twice for Struts managed beans

Posted by Lukasz Lenart <lu...@apache.org>.
You are probably right :) Please register an issue and target 2.3.25
as a fix version.


Regards
-- 
Łukasz
+ 48 606 323 122 http://www.lenart.org.pl/

2015-10-15 6:57 GMT+02:00 CRANFORD, CHRIS <Ch...@setech.com>:
> In a recent BeanPostProcessor implementation, I noticed our logic was being invoked twice in both the before and after initialization callbacks for struts constructed objects like actions, interceptors, etc while normal constructed Spring beans via component scanning were only being invoked once.
>
> After debugging in 3.2.24.1, I narrowed the issue down to the SpringObjectFactory implementation in Xwork2 at lines 194 to 197.  It seems XWork's implementation manually calls the before and after BeanPostProcessor callbacks.  Looking at the Spring source for AbstractAutowireCapableBeanFactory, it seems initializeBean's implementation also calls these callback methods too, which is what leads to re-evaluating the struts constructed objects twice.
>
> I believe the plugin is based on Spring 3.0.5 (IIRC) and even reviewing the code base at that release along with the latest 4.2.1 release, both confirm that initializeBean has always invoked the BeanPostProcessor callbacks internally and therefore, XWork's implementation really should not worry with manually invoking them too.
>
> Is there a technical reason why the SpringObjectFactory is doing this or is this an oversight?
> This just seems like a significant overhead on bean management that could be avoided, right?
>
> Thanks,
> Chris
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org