Skip to content

Objects created by FactoryBeans might get processed multiple times by BeanPostProcessors if beans are created lazily [SPR-11937] #16554

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Jul 1, 2014 · 4 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

Andreas Benneke opened SPR-11937 and commented

We wondered why the ScheduledAnnotationBeanPostProcessor schedules some of our jobs twice - and tracked this down to this situation.

The attached test case is a very simplified version:

  • Our beans are created lazily.
  • We have a set of beans which form a circle (BeanImpl1 requires BeanImpl2 and vice versa).
  • There are two instances of each bean in the application context, where one is the real implementation.
  • The other is a Proxy (created by the ProxyFactoryBean in real life, but a simple stripped down SimpleFactoryBean is sufficient in this case).
  • The Proxies are marked as primary=true and used for injection.
  • We added a TestPostProcessor counting the number of invocations of postProcessAfterInitialization per beanName for testing purposes.

The test cases reproduce simpler as well as eagerly created versions of this situation:

The TestPostProcessor is invoked only once per bean (as expected), if

  • everything is not created lazily (TestEager*).
  • there is no circle (not covered in the test cases).
  • there are no proxies and everything is defined in XML (TestLazyXml, TestEagerXml).
  • there are no proxies and everything is autowired (TestLazyAutowired, TestEagerAutowired).

But it is invoked twice (and the tests fail), if the proxies and objects are created lazily (TestLazyAutowiredFactoryBean, TestLazyXmlFactoryBean).

While tracing down this situation, we noticed that the isCurrentlyInCreation-logic is only applied to the FactoryBeans itself but not to the objects created by those factories - which might have helped to avoid this duplicate invocation of the BeanPostProcessor ...?


Affects: 3.2.9, 4.0.5

Attachments:

Backported to: 3.2.10

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

This turned out to be a side effect of FactoryBeans which happen to call BeanFactory.getBean from within their getObject() methods: Dependening on the initialization order when involved in a circular reference, their getObject() method might get called twice... which is not that big a deal itself, but unfortunately we also ended up post-processing the result twice in such a scenario. We now explicitly prevent this through a check that the specific FactoryBean's getObject() result hasn't been obtained before.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Andreas Benneke commented

Great!

We already suspected this to be a side effect of FactoryBeans looking up other beans themselves - but since Spring's own ProxyFactoryBean does exactly this, we thought that Spring should handle this elsewhere - which it does now... :-)

Thank you very much for this really quick resolution! :-D

Andreas

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

You're welcome, thanks for pointing this out!

BTW, it'd be great if you could verify your real system against either 4.0.6.BUILD-SNAPSHOT or 3.2.10.BUILD-SNAPSHOT, just to make sure that we actually solve your production problem, not just the extracted test case...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Andreas Benneke commented

Our production problem is solved by 3.2.10.BUILD-SNAPSHOT as well. :-)

Thank you again!

Andreas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants