Affects: spring-beans-5.2.0
Please allow the class
attribute for XML bean definitions which define the factory-bean
attribute. I got the point - The type is implicitly defined by the factory method's return type. So there is no need to define the class
attribute, because it's already "known".
But did you consider polymorph results of the factory bean? The class
attribute would allow me to specify the concrete type and I'd expect Spring to provide it with this type for injections (@Autowired
)
This would be helpful for Apache CXF jaxws, for example. From the manual (http://cxf.apache.org/docs/writing-a-service-with-spring.html):
<bean id="proxyFactory"
class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="demo.spring.HelloWorld"/>
<property name="address" value="http://localhost:9002/HelloWorld"/>
</bean>
<bean id="client" class="demo.spring.HelloWorld"
factory-bean="proxyFactory" factory-method="create"/>
(I assume that the CXF authors didn't know that the class
attribute of the second bean is ignored.)
I couldn't find a way to inject demo.spring.HelloWorld
via @Autowired
. Even if I use @Qualifier
it says "(...) required a bean of type 'demo.spring.HelloWorld' that could not be found.'
I think it's because of the polymorph return type Object
of the factory method (create()
).
However, this wouldn't be a problem with java-based configuration. I can get rid of the error message by replacing the second bean above with this code:
@Autowired
@Qualifier("proxyFactory")
private JaxWsProxyFactoryBean proxyFactory;
@Bean
public demo.spring.HelloWorld client() {
return (demo.spring.HelloWorld) proxyFactory.create();
}
But I'd really prefer to have everything in the xml file as shown above. This would be possible if Spring respected the class
attribute.
Probably you wonder why I don't simply use the <jaxws:client ...>
handler provided by CXF. Well, unfortunately they don't resolve property expressions (${user}). The issue is documented here: #20382 . Actually I'm using spring boot with @ImportResource
to load the XML file. It looks like the XML is imported before properties of application.properties
are available. See also this SO answer: https://stackoverflow.com/a/43980685/395879
Comment From: snicoll
I think it's because of the polymorph return type Object of the factory method (create()).
Correct.
However, this wouldn't be a problem with java-based configuration. I can get rid of the error message by replacing the second bean above with this code:
That isn't a proof of anything IMO since your code explicit cast the return type. If you need to do that for the Java code, it makes total sense that XML behaves this way. The FactoryBean
could expose the resolved generic rather, so that you don't have to do it this way.