Why I like Spring @Autowired for List types

Imagine having a tool that can automatically detect JPA and Hibernate performance issues. Wouldn’t that be just awesome?

Well, Hypersistence Optimizer is that tool! And it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, or Play Framework.

So, enjoy spending your time on the things you love rather than fixing performance issues in your production system on a Saturday night!

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 I’ve been taking advantage of this feature?

Since I was developing an application which 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.

@Component
public class MongoSchemaManager implements InitializingBean {

    @Autowired(required = false)
    private List<MongoCollectionDropOperator> mongoCollectionDropOperators;

    @Autowired(required = false)
    private List<MongoCollectionCreateOperator> mongoCollectionCreateOperators;

    @Override
    public void afterPropertiesSet() {
        if (mongoCollectionDropOperators != null) {
            for (MongoCollectionOperator mongoCollectionOperator : mongoCollectionDropOperators) {
                mongoCollectionOperator.execute();
            }
        }
        if (mongoCollectionCreateOperators != null) {
            for (MongoCollectionOperator mongoCollectionOperator : mongoCollectionCreateOperators) {
                mongoCollectionOperator.execute();
            }
        }
    }
}

This component gets injected the MongoCollectionCreateOperator and MongoCollectionDropOperator references, and it discovers those
even when added in specific module spring contexts.

So from one of our application module we get this mongo collection creator:

<bean id="messageMongoDbCollectionCleaner" class="mongo.storage.MongoCollectionDropOperator">
    <constructor-arg value="${mongo.messageCollection}"/>
</bean>

and from other module we have:

<bean id="sdcmMongoCollectionCreateOperator" class="mongo.storage.MongoCollectionCreateOperator">
    <constructor-arg value="baseSDCM"/>
    <constructor-arg>
        <bean class="org.springframework.data.mongodb.core.CollectionOptions">
            <constructor-arg name="size" value="1073741824" />
            <constructor-arg name="maxDocuments" value="1000000" />
            <constructor-arg name="capped" value="true" />
        </bean>
    </constructor-arg>
</bean>

I'm running an online workshop on the 20-21 and 23-24 of November about High-Performance Java Persistence.

If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.

This is all it takes, and it works great since the mongo schema management logic lies in the core, and the operators may be added dynamically without altering the schema management source code.

Transactions and Concurrency Control eBook

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.