@Cachebale 不使用 Ehcache 和 spring MVC Ehcache 不使用 Spring 缓存注释

@Cachebale not working with Ehcache and spring MVC Ehcache not working with Spring Caching Annotation

我的应用程序是 Spring MVC 应用程序。尝试使用 Spring 基于注释的缓存。但它不起作用。请参考我下面的代码

                1. pom.xml
                <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
                    <modelVersion>4.0.0</modelVersion>
                    <groupId>com.giggal.spring</groupId>
                    <artifactId>spring-tutorial-mvc</artifactId>
                    <version>0.0.1-SNAPSHOT</version>
                    <packaging>war</packaging>
                ......
                <dependencies>
                        <dependency>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-context</artifactId>
                            <version>4.3.4.RELEASE</version>
                        </dependency>
                        <dependency>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-context-support</artifactId>
                            <version>4.3.1.RELEASE</version>
                        </dependency>
                        <dependency>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-core</artifactId>
                            <version>4.3.4.RELEASE</version>
                        </dependency>
                        <dependency>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-beans</artifactId>
                            <version>4.3.4.RELEASE</version>
                        </dependency>
                        <dependency>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-web</artifactId>
                            <version>4.3.4.RELEASE</version>
                        </dependency>
                        <dependency>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-webmvc</artifactId>
                            <version>4.3.4.RELEASE</version>
                        </dependency>
                        <dependency>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-jdbc</artifactId>
                            <version>4.3.4.RELEASE</version>
                        </dependency>
                        <!-- Servlet -->
                        <dependency>
                            <groupId>javax.servlet</groupId>
                            <artifactId>servlet-api</artifactId>
                            <version>2.5</version>
                            <scope>provided</scope>
                        </dependency>
                        <dependency>
                            <groupId>javax.servlet.jsp</groupId>
                            <artifactId>jsp-api</artifactId>
                            <version>2.1</version>
                            <scope>provided</scope>
                        </dependency>
                        <dependency>
                            <groupId>javax.servlet</groupId>
                            <artifactId>jstl</artifactId>
                            <version>1.2</version>
                        </dependency>
                        <!-- EHCache -->
                        <dependency>
                            <groupId>net.sf.ehcache</groupId>
                            <artifactId>ehcache</artifactId>
                            <version>2.10.2.2.21</version>
                        </dependency>

                    </dependencies>
                </project>

2. My Spring app consists of two context xml config files, the first one app-ctx.xml only scans non-@Controller annotated beans:

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

                <context:component-scan base-package="com.giggal.spring">
                    <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation" />
                </context:component-scan>
                <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
                    <property name="cacheManager" ref="ehcache" />
                </bean>
                <bean id="ehcache"
                    class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
                    <property name="configLocation" value="classpath:ehcache.xml" />
                    <property name="shared" value="true" />
                </bean>

            .....

            </beans>

3. The second one mvc-config.xml contains all spring-mvc setup and scans @Controller annotated beans

                <?xml version="1.0" encoding="UTF-8"?>

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

                    <context:component-scan base-package="com.giggal.spring" use-default-filters="false">
                        <context:include-filter expression="org.springframework.stereotype.Controller"
                            type="annotation" />
                    </context:component-scan>


                    <mvc:annotation-driven />
                    <!-- 2. HandlerMapping : Used default handler mapping internally -->

                    <!-- 3. ViewResolver -->
                    <bean
                        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                        <!-- Example: a logical view name of 'showMessage' is mapped to '/WEB-INF/jsp/showMessage.jsp' -->
                        <property name="prefix" value="/WEB-INF/view/" />
                        <property name="suffix" value=".jsp" />
                    </bean>

                </beans>

4. The ehcache.xml used for caching with cache name emp :
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <defaultCache eternal="true" maxElementsInMemory="100"
        overflowToDisk="false" />
    <cache name="emp" maxElementsInMemory="10000" eternal="true"
        overflowToDisk="false" />
</ehcache>


5. The controller class UserController

@Controller
@RequestMapping(value = "/user/")
public class UserController {
@Autowired
    UserService userService; // Service which will do all data
                                // retrieval/manipulation work

@RequestMapping(value = "/getAllUsers/", method = RequestMethod.GET)
    public ModelAndView listAllUsers() {
        ModelAndView mav = new ModelAndView("user/user_list");
        List<User> users = userService.findAllUsers();
        mav.addObject("users", users);
        return mav;
    }

......
}

6. UserService class:

    @Service("userService")
    @Transactional
    public class UserServiceImpl implements UserService {

        private static final AtomicLong counter = new AtomicLong();

        private static List<User> users;

        static {
            users = populateDummyUsers();
        }

        @Cacheable("emp") 
        public List<User> findAllUsers() {
            System.out.println("execute getEmployee method..");
            return users;
        }  
    ....
    }

但是 findAllUsers() 方法调用永远不会被缓存,每次我总是得到 sysout "execute getEmployee method.."。这可能是什么原因造成的?关于缓存注释,我肯定还有一些不明白的地方。

But the same code is working as below
1. 
@Configuration
@EnableCaching
@ComponentScan({ "com.giggal.*" })
public class AppConfig {

    @Bean
    public CacheManager cacheManager() {
        return new EhCacheCacheManager(ehCacheCacheManager().getObject());
    }

    @Bean
    public EhCacheManagerFactoryBean ehCacheCacheManager() {
        EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean();
        cmfb.setConfigLocation(new ClassPathResource("ehcache.xml"));
        cmfb.setShared(true);
        return cmfb;
    }
}

---
@Controller
@RequestMapping(value = "/user/")
public class UserController {



@RequestMapping(value = "/getAllUsers/", method = RequestMethod.GET)
    public ModelAndView listAllUsers() {
           AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(com.giggal.spring.AppConfig.class);
            UserService obj = (UserService) context.getBean("userService");
            List<User> users = obj.findAllUsers();
        ModelAndView mav = new ModelAndView("user/user_list");
        //List<User> users = userService.findAllUsers();
        mav.addObject("users", users);
        return mav;
    }
..}

请建议使用注释的机制

在你的xml配置中,你需要添加

<cache:annotation-driven />

以便 spring 选择 @Cacheable 注释。

有关详细信息,请参阅 https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/annotation/EnableCaching.html

@EnableCaching and <cache:annotation-driven/> are responsible for registering the necessary Spring components that power annotation-driven cache management, such as the CacheInterceptor and the proxy- or AspectJ-based advice that weaves the interceptor into the call stack when @Cacheable methods are invoked.