Search code examples
javaspringspring-cache

Springcache not working only with XML configuration


I am implementing Springcache with XML configuration and want to get rid of all the annotations. I just want to replace the annotations in the applicationContext.xml file. Here is my code -

//DummyBean.java
package com.spring.example;
interface DummyBean {
    public String getCity();
}

//DummyBeanImpl.java
package com.spring.example;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;

@EnableCaching
@CacheConfig(cacheNames={"myCache"})
public class DummyBeanImpl implements DummyBean {

    private String city = "New York";

    @Cacheable()
    public String getCity() {
        System.out.println("DummyBean.getCity() called!");
        return city;
    }
}

SpringAwareAnnotationXMLConfig.java

package com.spring.example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class SpringAwareAnnotationXMLConfig {

  public static void main(String[] args) throws Exception {
    AbstractApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");

    DummyBean personService = (DummyBean) context.getBean("myBean");
    System.out.println(personService.getCity());
    System.out.println(personService.getCity());
    System.out.println(personService.getCity());

    ((AbstractApplicationContext) context).close();
  }
}

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:cache="http://www.springframework.org/schema/cache"
           xmlns:c="http://www.springframework.org/schema/c"
           xmlns:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
                               http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd
                               http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd>


  <context:annotation-config/>
  <cache:annotation-driven cache-manager="cacheManager"/>
  <context:component-scan base-package="com.spring"/>

  <bean id="myBean" class="com.spring.example.DummyBeanImpl"/>

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

  <cache:advice id="cacheAdvice" cache-manager="cacheManager">
    <cache:caching cache="myCache">
      <cache:cacheable method="getCity"/>
    </cache:caching>
  </cache:advice>
</beans>

As you can see if I keep the @EnableCaching, @CacheConfig, @Cacheable annotations in the Java code, then caching is working fine and I am getting the following output -

DummyBean.getCity() called!
New York
New York
New York

But if I remove the annotations, then I am getting the following output -

DummyBean.getCity() called!
New York
DummyBean.getCity() called!
New York
DummyBean.getCity() called!
New York

This means that the caching didn't work!

But my expectation is that in the applicationContext.xml file I have already enabled the cache by <cache:annotation-driven cache-manager="cacheManager"/>, I have already mentioned the cachename and I have already configured the cache with the method names where caching is to be implemented. So if I omit the annotations, I should get the desired output. But why I am not getting?

Thanks Nirmalya


Solution

  • When using XML configured aspects you will also need to add an aop:config section to have the aspect applied.

    <aop:config>
        <aop:advisor advice-ref="cacheAdvice" pointcut="execution(* com.spring.example.DummyBean+.*(..))"/>
    </aop:config>
    

    Assuming DummyBean is an interface implemented by com.spring.example.DummyBeanImpl this should do the trick. This states that you want to apply the cacheAdvice (the aspect) to the bean matching the expression.

    See also the reference guide