Search code examples
springspring-annotations

Using Constructor Arguments with Spring cache:annotation-driven


I receive the following exception when I add cache:annotation-driven to my application context:

Superclass has no null constructors but no arguments were given

I have a class called PersistController, which has methods annotated with @Cachable(..), and I am declaring an instance within the application context as follows:

<!-- The culprit, for whatever reason -->
<cache:annotation-driven />

<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
    <property name="caches">
        <set>
            <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="primaryTest"/>
            <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="secondaryTest"/>
        </set>
    </property>
</bean>

<!-- The problem began when I started requiring a String in the constructor. -->
<bean id="persistController" class="com.sei.poc.controller.PersistController" >
    <constructor-arg> <value>${cache.nextVersionPostfix}</value></constructor-arg>  
</bean>

When I remove the cache:annotation-driven line, the error goes away, and I instead receive an error indicating the annotated caching components are not working (obviously). This means that the PersistController declared above is declared properly and Spring is fully capable of calling the proper constructor, resolving the property, and injecting the string as an argument.

So why the error when I add cache:annotation-driven?

I believe this has something to do with Spring automatically instantiating an instance of classes with @Cacheable(..), or any of the Spring cache annotations. If this is the case, I would like to know if there is a way I can specify my property as an argument in its construction.

If I cannot declare constructors for these classes, (and if you know the answer, I will assume you understand the spring-context-flow better than I) willl an @Autowired or @Value(..) annotation allow the generated class to detect the property?

Thank you all for reading.


Solution

  • I have found an answer to the second part of my question, whether or not an @Value() annotation with be resolved when spring loads the class with cache:annotation-driven.

    The answer is yes, I had added the following line in my PersistController and the issue has been resolved:

    @Value("${cache.currentVersionPostfix}")
    private String keyPostfix;
    

    I am still uncertain if I can supply an argument in a constructor loaded with cache:annotation-driven. That being said, I will hold off on accepting this as an answer and accept one that answers that question.