简体   繁体   中英

How to tell Spring to instantiate selected beans without providing constructor args?

Problem:

I'm integrating with a library written by the other team. This library provides a set of classes that I'm using in my Spring-driven application. Every bean in my application is in singleton scope.

Also 99% of the classes from that library uses constructor injection.

I'm using XML and my configuration looks very similar to the following:

<bean id="lib.service1" class="lib.Service1"/>
<bean id="lib.service2" class="lib.Service2">
 <constructor-arg ref="lib.service1"/>
</bean>
<bean id="lib.service3" class="lib.Service3">
 <constructor-arg ref="lib.service1"/>
</bean>
<bean id="lib.service4" class="lib.Service3">
 <constructor-arg ref="lib.service2"/>
 <constructor-arg ref="lib.service3"/>
</bean>
<!-- other bean definitions -->
<bean id="lib.serviceN" class="lib.ServiceN">
 <constructor-arg ref="lib.serviceX"/>
 <constructor-arg ref="lib.serviceY"/>
 <constructor-arg ref="lib.serviceZ"/>
 <constructor-arg ref="lib.serviceK"/>
</bean>
<!-- other bean definitions -->

What I want:

I want to simplify my configuration to not to use bean IDs and ask spring to do constructor injection for me based on the type of arguments in the bean constructors. I can also ask library implementers to add @Inject annotation to the class constructors (the 99% of the classes have just one public constructor), but this is all that I can ask wrt refactoring of their library.

And eventually I want to have just following in my spring config (doesn't work, but illustrates the idea):

<bean class="lib.Service1"/>
<bean class="lib.Service2"/>
<bean class="lib.Service3"/>
<!-- ... -->
<bean class="lib.ServiceN"/>

Here I'm expecting Spring to figure out that I want to use constructor injection for all those beans and infer bean instances based on the constructor argument types.

Note that I cannot use component scan - they have one package (lib. in the example given above) and some classes in that package are useless for my application and too expensive to be needlessly created. Plus some classes that I'm not using are experimental and can be changed/renamed/removed without prior notice.

Add autowire="constructor" , assuming these bean types only have one constructor and that the corresponding parameters match single beans.

<bean class="lib.Service1" autowire="constructor"/>

From the documentation

  1. "constructor"

Analogous to "byType" for constructor arguments. If there is not exactly one bean of the constructor argument type in the bean factory, a fatal error is raised. Note that explicit dependencies, ie "property" and "constructor-arg" elements, always override autowiring. Note: This attribute will not be inherited by child bean definitions. Hence, it needs to be specified per concrete bean definition.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM