Skip to content

INT-4517: Refactor beans in IntegrationRegistrar #2537

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

Merged
merged 2 commits into from
Aug 15, 2018

Conversation

artembilan
Copy link
Member

JIRA: https://jira.spring.io/browse/INT-4517

The IntegrationRegistrar populates beans into the application context
too early and when the allowBeanDefinitionsOverride is disabled we
end up with the BeanDefinitionOverrideException just because end-user
beans are applied later.

  • Move most of the bean definitions which can be overridden in the target
    application from the IntegrationRegistrar into the
    DefaultConfiguringBeanFactoryPostProcessor
  • Revise their registration logic to be sure that some of them are
    registered only once in the parent context nad others are registered
    in the child context as well
  • Refactor a DslIntegrationConfigurationInitializer do not register
    an IntegrationFlowDefinition.ReplyProducerCleaner in the child context
    one more time: it doesn't bring any local store within the current
    child context
  • Introduce a NoBeansOverrideAnnotationConfigContextLoader in tests
    to ensure that in some test-cases we disallow an
    allowBeanDefinitionsOverride as it is now in Spring Boot since it is
    enabled by default in the Spring Framework

Copy link
Contributor

@garyrussell garyrussell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one comment/question - and a typo in the commit comment s/nad/and/

if (!registry.containsBeanDefinition(INTEGRATION_FLOW_BPP_BEAN_NAME)) {
registry.registerBeanDefinition(INTEGRATION_FLOW_BPP_BEAN_NAME,
new RootBeanDefinition(IntegrationFlowBeanPostProcessor.class));
registry.registerBeanDefinition(INTEGRATION_FLOW_CONTEXT_BEAN_NAME,
new RootBeanDefinition(StandardIntegrationFlowContext.class));
}

if (!configurableListableBeanFactory.containsBean(INTEGRATION_FLOW_REPLY_PRODUCER_CLEANER_BEAN_NAME)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this be a problem if the child context is loaded by a different class loader?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gary, do you mean that IntegrationFlowDefinition is going to be loaded one more time in the child context when it uses its own class loaded?
Then indeed that private static final Set<MessageProducer> REFERENCED_REPLY_PRODUCERS = new HashSet<>(); store is going to be a fresh in that class loaded...
But I'm not so good in such a low level of JVM.
So, please, confirm how it is going and I'll change respectively or let's leave it as is!

Thanks

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's what I meant; it's unlikely because, normally, class loaders are hierarchical and the child loader will find the existing class instance in the parent loader.

However, it's possible, so the question is whether saving an extra bean in the child context is worth the risk of a memory leak; but I think the risk is very small - weird class loaders combined with a lot of dynamic flow recycling, so I really don't mind either way - I just thought it was worth raising.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just reverted that change.

Thank you for clarification!

JIRA: https://jira.spring.io/browse/INT-4517

The `IntegrationRegistrar` populates beans into the application context
too early and when the `allowBeanDefinitionsOverride` is disabled we
end up with the `BeanDefinitionOverrideException` just because end-user
beans are applied later.

* Move most of the bean definitions which can be overridden in the target
application from the `IntegrationRegistrar` into the
`DefaultConfiguringBeanFactoryPostProcessor`
* Revise their registration logic to be sure that some of them are
registered only once in the parent context nad others are registered
in the child context as well
* Refactor a `DslIntegrationConfigurationInitializer` do not register
an `IntegrationFlowDefinition.ReplyProducerCleaner` in the child context
one more time: it doesn't bring any local store within the current
child context
* Introduce a `NoBeansOverrideAnnotationConfigContextLoader` in tests
to ensure that in some test-cases we disallow an
`allowBeanDefinitionsOverride` as it is now in Spring Boot since it is
enabled by default in the Spring Framework
Regsiter all the required infrastructure beans in all the application
contexts to avoid class loader issue for `static` store access
@garyrussell garyrussell merged commit 5e47a6a into spring-projects:master Aug 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants