Spring MVC - 在应用程序级别进行缓存

时间:2015-08-18 11:30:37

标签: java spring-mvc caching request single-page-application

我使用Spring MVC在AngularJS中开发单页面应用程序。

首先请求登录服务,然后我呼叫服务A,B和C. 这会产生我在客户端构建页面所需的数据。

在这些服务的每一个中,A,B和C需要调用一些DAO - 它们从数据库中提取数据。 DAO名称是X.

现在,当用户在应用程序中导航时,他会一次又一次地调用这些服务, 而且我每次都不会去DB。 我想在登录时只去DB一次(对于那个matther-dao' X')并将这些数据保存在某个Cache中。

我的解决方案是将来自X的MAP数据保存在某个bean中:

data4 <- data2[1:3]
#Your answer for the second part here:
data3 <- data2[,sapply(data2,function(col)length(unique(col)))==3]
merge(data3,data4)

我的问题是这是正确的解决方案吗? 因为应用程序以这种方式将数据保存在内存中,这看起来像是糟糕的设计。 任何人都可以建议更好的解决方案吗?

希望我足够清楚。 感谢。

2 个答案:

答案 0 :(得分:2)

您可以使用@Cacheable注释缓存方法的结果。这是一种优化的机制,无需编写整个HashMap get(),put()逻辑。

要使用它,您需要定义CacheManager并启用缓存。这是一个使用基于Java的配置的自包含示例。 Spring documentation

中的更多信息

但是,鉴于您的结果最终来自DAO,您应该使用EH-cache,Terracotta等,因为它可以在实体级别缓存,这将允许在您的应用程序中重复使用实体

public class CacheTest {
    public static class Service {
        @Cacheable("horseCache")
        public List<String> getX(String key) {
            System.out.println("Called for " + key);
            return Arrays.asList(key + "...");
        }
    }

    @Configuration
    @EnableCaching
    public static class Config {
        @Bean
        public CacheManager cacheManager() {
            SimpleCacheManager cacheManager = new SimpleCacheManager();
            cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("horseCache")));
            return cacheManager;
        }
    }

    public static void main(String[] args) {
        // Inline application context definition to support self-contained example
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClass(Service.class);
        GenericBeanDefinition configDefition = new GenericBeanDefinition();
        configDefition.setBeanClass(Config.class);
        context.registerBeanDefinition("bean", beanDefinition);
        context.registerBeanDefinition("config", configDefition);
        context.refresh();

        // actual example
        Service bean = context.getBean(Service.class);
        System.out.println(bean.getX("foo"));
        System.out.println(bean.getX("bar"));
        System.out.println(bean.getX("foo")); // demonstrate 2nd call is cached
    }

}

输出

Called for foo
[foo...]
Called for bar
[bar...]
[foo...]

答案 1 :(得分:0)

你可以去Ehcache。 查看有关网页缓存的this链接。
在您的情况下,您可以在web.xml中定义类似于登录的内容 -

select * from ( select item,identifier,quantity,methodid, row_number() over(partition item,identifier,methodid) as rank)

因此,一旦您的网页在Web服务调用后加载,它将被缓存。