Skip to content
This repository was archived by the owner on Feb 23, 2023. It is now read-only.

Add support for FactoryBean that specify the target type using FactoryBean.OBJECT_TYPE_ATTRIBUTE #1155

Closed
artembilan opened this issue Oct 18, 2021 · 5 comments
Assignees
Labels
type: enhancement A general enhancement
Milestone

Comments

@artembilan
Copy link
Contributor

There are some use-cases when FactoryBean target type cannot be determined from generics or some other info during beanFactory.resolveDependency().
For this purpose we rely on the FactoryBean.OBJECT_TYPE_ATTRIBUTE attribute setting on BeanDefinition.
Such an attribute should be copied to the target generated code.
This way we won't need to develop our own simple BeanRegistrationWriter just for a sake of this attribute carrying on.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Oct 18, 2021
artembilan added a commit to artembilan/spring-native that referenced this issue Oct 22, 2021
Fixes spring-attic#1155
Related to spring-attic#1134

The `FactoryBean.OBJECT_TYPE_ATTRIBUTE` is crucial for those `FactoryBean` impls
which does not expose the target type during compilation.

* Add `FactoryBean.OBJECT_TYPE_ATTRIBUTE` as a candidate for the
`DefaultBeanRegistrationWriter.getAttributeFilter()` since that one is `false` by default anyway
* Rework `IntegrationApplication` to reflect the current Spring Boot state
* Use `spring-integration-5.5.6-SNAPSHOT` for the latest bean definition changes over there

The `build.sh -a` now passes for the integration sample.
Cannot confirm in the native mode since GraalVM doesn't work well on Windows: too long command line.
Need to build classpath file (jar with respective META-INF) somehow...
@snicoll
Copy link
Contributor

snicoll commented Oct 23, 2021

I didn't see this issue and commented on the PR instead #1172 (comment)

Let's keep the conversation here please. I'd like to understand what bean definitions in Spring Integration require this.

@snicoll snicoll added the status: waiting-for-feedback We need additional information before we can continue label Oct 23, 2021
@artembilan
Copy link
Contributor Author

See the related issue: #1030.

Perhaps that one is more generic than this one, so it might be considered as duplication.

For more context.

Spring Integration has a @MessagingGateway interfaces parsing. This is done by the GatewayProxyFactoryBean, which does know the target type even during bean definition. See its ctor:

public GatewayProxyFactoryBean(Class<?> serviceInterface) {

But anyway this info is not available during autowiring. See the IntegrationApplication as a sample:

@Bean
public IntegrationFlow controlBusControllerFlow(ControlBusGateway controlBusGateway) {
   ...
}

Where that ControlBusGateway is like this:

@MessagingGateway(defaultRequestChannel = "controlBus.input")
public interface ControlBusGateway {
   ...
}

Spring Integration scans for that interface and expose a GatewayProxyFactoryBean.
The mentioned FactoryBean.OBJECT_TYPE_ATTRIBUTE is used then when this interface type is resolved for the autowiring into that bean method argument.

Probably using a setBeanClass() instead is not a way: we won't be able to autowire the whole GatewayProxyFactoryBean in the end since its type is lost.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Oct 25, 2021
@snicoll
Copy link
Contributor

snicoll commented Oct 27, 2021

Thanks for the additional feedback. I don't think exposing the factory type in the generated code is the right way to fix this. After all, we have at build time a complete overview of the bean definitions and their state so we should be able to write back something that represents the correct state of the application context without relying on the context to do extra hops for us.

I've been investigating a few options but they all have drawbacks. I'll investigate some more this week.

snicoll added a commit to snicoll/spring-native that referenced this issue Oct 27, 2021
@artembilan
Copy link
Contributor Author

Yes, I also had the same doubt about such an extra type info which is really available for us at build time.
And I have just confirmed with tests in Spring Integration that RootBeanDefinition.setTargetType() works for me for all the use-cases.
Only the problem that Spring Native does not carry that info into a generated BeanDefinition, so, I still cannot run Spring Integration properly on AOT.

Thanks

artembilan added a commit to artembilan/spring-native that referenced this issue Oct 28, 2021
Fixes spring-attic#1155
Related to spring-attic#1134

The `FactoryBean.OBJECT_TYPE_ATTRIBUTE` is crucial for those `FactoryBean` impls
which does not expose the target type during compilation.

* Add `FactoryBean.OBJECT_TYPE_ATTRIBUTE` as a candidate for the
`DefaultBeanRegistrationWriter.getAttributeFilter()` since that one is `false` by default anyway
* Rework `IntegrationApplication` to reflect the current Spring Boot state
* Use `spring-integration-5.5.6-SNAPSHOT` for the latest bean definition changes over there

The `build.sh -a` now passes for the integration sample.
Cannot confirm in the native mode since GraalVM doesn't work well on Windows: too long command line.
Need to build classpath file (jar with respective META-INF) somehow...
@snicoll snicoll changed the title The DefaultBeanRegistrationWriter.getAttributeFilter() must match at least to FactoryBean.OBJECT_TYPE_ATTRIBUTE by default Add support for FactoryBean constructor Nov 3, 2021
@snicoll snicoll added theme: aot type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on status: feedback-provided Feedback has been provided labels Nov 3, 2021
@snicoll snicoll self-assigned this Nov 3, 2021
@snicoll snicoll added this to the 0.11.0-RC1 milestone Nov 3, 2021
@snicoll snicoll closed this as completed in f76a105 Nov 4, 2021
@snicoll snicoll changed the title Add support for FactoryBean constructor Add support for FactoryBean that specify the target type using FactoryBean.OBJECT_TYPE_ATTRIBUTE Nov 4, 2021
@snicoll
Copy link
Contributor

snicoll commented Nov 4, 2021

I changed my mind and I added a dedicated writer for the case of a FactoryBean whose target type is not defined upfront but via the attribute. It does some additional checks to verify that the attribute is compatible with the bounds of the factory bean.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: enhancement A general enhancement
Development

Successfully merging a pull request may close this issue.

3 participants