Skip to content

Allow Spring Boot to determine type created by GatewayProxyFactoryBean #1423

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

Conversation

wilkinsona
Copy link
Member

This PR fixes the Spring Integration portion of spring-projects/spring-boot#2811. Please see the commit message for further details. I've tested the changes against a Spring Boot 1.2.4 snapshot and confirmed that it resolves the problem.

Spring Boot's @ConditionalOnBean can be used to activate some
configuration when a bean of a particular type is present in the
application context. To avoid early initialization, the search for
beans is performed without instantiating them, i.e. it relies on the
information that's available from the bean's class and its bean
definition. This causes a problem with GatewayProxyFactoryBean as its
a FactoryBean<Object> so Boot's best guess is that the bean that's
produced by the factory will be an Object. For cases where the bean's
type signiture does not contain enougn information to determine its
type,  Boot looks at an attribute, factoryBeanObjectType, on the
factory bean's definition. The value of this attribute can be a Class
or a String class name.

This commit updates MessagingGatewayRegistrar to set the
value of factoryBeanObjectType attribute to be the configured
service interface for the gateway.
@garyrussell
Copy link
Contributor

@@ -163,7 +164,10 @@ else if (StringUtils.hasText(asyncExecutor)) {

gatewayProxyBuilder.addConstructorArgValue(serviceInterface);

return new BeanDefinitionHolder(gatewayProxyBuilder.getBeanDefinition(), id);
AbstractBeanDefinition beanDefinition = gatewayProxyBuilder.getBeanDefinition();
beanDefinition.addMetadataAttribute(new BeanMetadataAttribute("factoryBeanObjectType", serviceInterface));
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps we should open issues against Spring Framework and Spring Boot to move the constant FACTORY_BEAN_OBJECT_TYPE to SF - e.g. to BeanMetadataAttribute.

It's a bit brittle to use a literal here and it is possible that other projects may need similar.

For now, I will move this to a constant within SI during the merge.

I will also address @artembilan 's suggestion about fixing the getObjectType() when the service interface is null.

Copy link
Member Author

Choose a reason for hiding this comment

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

On the Boot call yesterday, @philwebb mentioned some of the code moving into Spring Framework. It hasn't happened yet, AFAIK. Hopefully Phil can comment with the latest.

Copy link
Contributor

Choose a reason for hiding this comment

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

Note that this solution won't work if the service interface is a property placeholder (rare, perhaps, but possible).

We may just have to live with that, or boot will have to resolve property placeholders in BeanTypeRegistry.determineTypeFromDefinitionAttribute().

Copy link
Member

Choose a reason for hiding this comment

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

@garyrussell
Copy link
Contributor

With polish: garyrussell@29a6bf5

/cc @artembilan

@artembilan
Copy link
Member

Guys, nothing to complain about.
If @wilkinsona confirms, that the fix work well with Boot, we can go ahead and merge.

@garyrussell , be careful with back port to 4.1.x: your simple change for the reactor.fn.Functions import order may course conflict. 4.1 is based on the Reactor 1.0, where Functions is on the other package.
From other side: do we really need to backport this?
@wilkinsona , do we need a fix for Boot 1.2.x ?

Thank you both

@garyrussell
Copy link
Contributor

@artembilan - @wilkinsona 's PR is against 4.1.x so it certainly sounds like it's needed in 4.1

I just did my polishing on master hence, the reactor issue - will be sure to verify on backport

@artembilan
Copy link
Member

Doh. I have missed that from the PR header.
Thank you and I believe you.
So, please, go ahead and merge

@garyrussell
Copy link
Contributor

Reverting the change to the GPFB - it caused an undesired side-effect (early access to the type should return null).

@garyrussell
Copy link
Contributor

Merged as 2653ce9 and cherry-picked to 4.1.x.

cc: spring-projects/spring-boot#2811

@chrylis
Copy link

chrylis commented Apr 16, 2015

Much appreciated! What will be the minimum release versions required for this to work?

@garyrussell
Copy link
Contributor

4.1.4; we don't currently have a schedule for its release (we only just released 4.1.3).

When do you need it?

In the meantime, you can test with 4.1.4.BUILD-SNAPSHOT (from the snapshot repo).

@garyrussell
Copy link
Contributor

Just to be clear, that's Spring Integration - we'll need to coordinate with the boot guys for a boot version.

@chrylis
Copy link

chrylis commented Apr 17, 2015

I have a library to update when it's ready. I'm keeping the old-style explicit import for now instead of using autoconfiguration.

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.

5 participants