An XML-only solution would simply have you declare a <bean>
of the "external" type and provide an autowire
value of "byType"
.
Controls whether bean properties are "autowired". This is an automagical process in which bean references don't need to be coded explicitly in the XML bean definition file, but rather the Spring container works out dependencies.
[...]
- "byType" Autowiring if there is exactly one bean of the property type in the container. If there is more than one, a fatal error is raised, and you cannot use byType autowiring for that bean. If there is none, nothing special happens.
The explanation is a little confusing in that we expect multiple InterfaceType
beans, but the actual field is of type List
and Spring will be able to dynamically instantiate one and add all the InterfaceType
beans to it, then inject it.
Your XML would simply look like
<bean id="service" class="...Service" autowire="byType">
</bean>
My original suggested solution made use of SpEL.
In the module that does have Spring dependencies, create a DTO
@Component(value = "beanDTO")
public class BeanDTO {
@Autowire
private List<InterfaceType> implementingBeans;
public List<InterfaceType> getImplementingBeans() {
return implementingBeans;
}
}
and then use SpEL to retrieve the value of implementingBeans
from the beanDTO
bean.
<bean id="service" depends-on="beanDTO" class="...Service">
<property name="implementingBeans" value="{beanDTO.implementingBeans}" />
</bean>
Spring will create the BeanTDO
bean, inject all the beans that are of type InterfaceType
. It will then create the service
bean and set its property from beanDTO
's implementingBeans
property.
Following comments on question:
In an effort to be more JSR 330 compliant, Spring has introduced support for Java EE's javax.inject
package. You can now annotate your injection targets with @javax.inject.Inject
instead of @Autowired
. Similarly, you can use @Named
instead of @Component
. The documentation has more details.