DevOps Zone is brought to you in partnership with:

I am a software architect passionate about software integration, high scalability and concurrency challenges. Vlad is a DZone MVB and is not an employee of DZone and has posted 55 posts at DZone. You can read more from them at their website. View Full User Profile

Why I like Spring @Autowired for List Types

10.04.2013
| 7836 views |
  • submit to reddit

Spring Framework dependency injection is great, and almost every Java developer uses it nowadays. Using @Autowired to inject Java Beans is trivial, but we can also use this annotation for java.util.List, or java.util.Map as well. The former will inject a list of all Java Beans matching the List's Generic type, while the latter will create a map of these beans mapped by their names.

How have I been taking advantage of this feature?

Since I was developing an application that has a framework module and a specific customer implementation module, there were cases where I needed to add a common logic in the framework module which would detect all Beans of a given type, even the ones defined in the specific module.

In the following example I will demonstrate how this works. My task was to have a MongoDB schema management component. The manager is included in the framework module, and auto-scanned by Spring.

01.@Component
02.publicclassMongoSchemaManager implementsInitializingBean {
03.  
04.    @Autowired(required = false)
05.    privateList<MongoCollectionDropOperator> mongoCollectionDropOperators;
06.  
07.    @Autowired(required = false)
08.    privateList<MongoCollectionCreateOperator> mongoCollectionCreateOperators;
09.  
10.    @Override
11.    publicvoidafterPropertiesSet() {
12.        if(mongoCollectionDropOperators != null) {
13.            for(MongoCollectionOperator mongoCollectionOperator : mongoCollectionDropOperators) {
14.                mongoCollectionOperator.execute();
15.            }
16.        }
17.        if(mongoCollectionCreateOperators != null) {
18.            for(MongoCollectionOperator mongoCollectionOperator : mongoCollectionCreateOperators) {
19.                mongoCollectionOperator.execute();
20.            }
21.        }
22.    }
23.}

This MongoCollectionCreateOperator and MongoCollectionDropOperator List references are discovered even when being added in other modules' Spring contexts.

So, from one of our application's customer-specific Modules we get this Mongo collection creator:

1.<beanid="messageMongoDbCollectionCleaner"class="mongo.storage.MongoCollectionDropOperator">
2.    <constructor-argvalue="${mongo.messageCollection}"/>
3.</bean>

And from another customer-specific module we have:

01.<beanid="sdcmMongoCollectionCreateOperator"class="mongo.storage.MongoCollectionCreateOperator">
02.    <constructor-argvalue="baseSDCM"/>
03.    <constructor-arg>
04.        <beanclass="org.springframework.data.mongodb.core.CollectionOptions">
05.            <constructor-argname="size"value="1073741824"/>
06.            <constructor-argname="maxDocuments"value="1000000"/>
07.            <constructor-argname="capped"value="true"/>
08.        </bean>
09.    </constructor-arg>
10.</bean>

This is all it takes, and it works great since the Mongo schema management logic lies in the core module and the operators are discovered without altering the schema management source code, and without having to explicitly define the core bean in every customer specific application. 



Published at DZone with permission of Vlad Mihalcea, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)