Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Beans: Scan for Converters, Inject into CustomConversionServiceFactory

I've got a MyAppConversionServiceFactoryBean which I'm registering like:

<bean id="conversionService" class="com.MyProject.MyAppConversionServiceFactoryBean">
    <property name="messageSource" ref="messageSource"/>
    <property name="converters">
        <set>
            <bean class="com.MyProject.XRepresentationConverter" />
            <bean class="com.MyProject.YRepresentationConverter" />
            <bean class="com.MyProject.ZRepresentationConverter" />
        </set>
    </property>
</bean>

I can continue to list every converter we write into this list, but I'd love to be able to configure it such that this isn't necessary and that converters will automatically register themselves somehow with my factory.

Sidebar 1: If that's not possible with a custom factory, is it possible with the default spring one?

Sidebar 2: If neither the first part nor Sidebar 1 is possible, is it possible to @Autowired the conversionService into the converters (so they can easily call one another)? Attempting to @Autowired ConversionService conversionService has previously given me issues due to not being able to wire the conversionService into an object while it's still busy creating the service.

Note: We're using Spring, but not Spring MVC. I have no control over that, so any solutions on that route will be unfortunately unusable. I can change pretty much anything else about the configuration and Java classes, just not the overarching tools.

like image 392
Patrick Avatar asked Aug 23 '12 15:08

Patrick


1 Answers

@Vikdor's comment on the question pointed me in the right direction.

Spring is apparently capable (and no one I asked in person knew this) of gathering collections of beans through the scanning process with @Autowired annotations. Here's what I needed to achieve the same effect I got from the configuration in the post:

applicationContent.xml must have:

<context:component-scan base-package="com.MyProject"/>
<bean id="conversionService" class="com.MyProject.MyAppConversionServiceFactoryBean" />


MyAppConversionServiceFactoryBean.java:

public class MyAppConversionServiceFactoryBean implements
        FactoryBean<ConversionService>, InitializingBean {

    @Autowired
    private Set<BaseConverter> converters;

}


And then all of my converters now have the @Component annotation.

Relevant Docs on @Autowired do briefly mention that it can be used to collect all beans of a type, but I wouldn't have known that it could be done into any collection type without this thread by Grzegorz Oledzki which addresses the generic form of my question, but takes it down a philosophical route.

like image 112
Patrick Avatar answered Oct 13 '22 21:10

Patrick