`
yunzhu
  • 浏览: 1146134 次
  • 性别: Icon_minigender_1
  • 来自: 南京
博客专栏
B2b19957-cda7-3a9e-83a0-418743feb0ca
监控应用服务器
浏览量:110027
2e8be8be-e51f-346c-bcdd-12623c9aa820
Web前端开发
浏览量:119813
Bfa5df64-a623-34b9-85b8-ef3ce2aed758
经典异常的解决
浏览量:204676
社区版块
存档分类
最新评论

Spring与ehcache整合,通过Spring原生注解使用缓存

阅读更多

最原始的进行缓存的方式:

最原始的使用缓存的方式是通过一个全局map保存获取过的数据,下次获取数据时先从map中提取,如果有就直接返回,如果没有就从数据库中去读取,然后放入map中,当然,在做更新操作时需要同步更新这个map中的数据。这种方式虽然原始,但是在一些简单的场景下已经够用了,比如Java的类加载器就是使用的这种方式缓存加载过的class。
 
 
通过ehcache以编程方式使用缓存:
跟上面的方式相同,但是缓存通过ehcache去管理,当然比使用map有N多种好处,比如缓存太大了快达到上限之后,将哪一部分缓存清除出去。这种方式完全是通过代码的方式使用ehcache缓存,虽然自由,却也很麻烦;有些比如单纯的场景下,不需要如此麻烦,直接通过注解就行了。
以前在Spring项目中要通过注解的方式使用缓存,比如借助一个jar包:ehcache-spring-annotations.jar,可以在googlecode上面下载,不过已经很久没有更新过了。
 
 
使用ehcache-spring-annotations.jar

Spring配置文件:
<?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:ehcache= "http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
      xsi:schemaLocation= "
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd">
 
      <ehcache:annotation-driven cache-manager ="ehcacheManager" />
      <ehcache:config cache-manager = "ehcacheManager">
           <ehcache:evict-expired-elements
               interval= "60" />
      </ehcache:config >
      <bean id = "ehcacheManager"
           class= "org.springframework.cache.ehcache.EhCacheManagerFactoryBean" >
           <property name = "configLocation" value= "classpath:ehcache.xml" />
      </bean >
</beans>

共有两个注解:
  • @Cacheabele      :指定方法使用缓存
  • @TriggersRemove  :从缓存中移除对象
在查询的方法上使用缓存
@Cacheable(cacheName="platform.config")
 
在删除或更新的方法上清空缓存:
@TriggersRemove(cacheName="platform.config", when=When.AFTER_METHOD_INVOCATION , removeAll=true)
public void updateConfig(SystemConfig config) {
     this.configDao.update(config);
}
 
对于这种方式,这里不做详细探讨。
在Spring 3.1以前,必须借助以上jar包才能支持以注解的方式使用缓存,但是从Spring 3.1开始,已经提供了原生的注解支持,当然也更加强大。
 
 
 
Spring 3.1及以上版本的原生注解支持

Spring配置文件:
<?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:cache= "http://www.springframework.org/schema/cache"
      xsi:schemaLocation= "
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
 
      <cache:annotation-driven cache-manager ="ehcacheCacheManager" />
      <bean id = "ehcacheCacheManager" class= "org.springframework.cache.ehcache.EhCacheCacheManager"
           p:cacheManager-ref= "ehcacheManager" />
      <bean id = "ehcacheManager"
           class= "org.springframework.cache.ehcache.EhCacheManagerFactoryBean" >
           <property name = "configLocation" value= "classpath:ehcache.xml" />
      </bean>
</beans>
 

 
Spring原生的缓存的注解共有四个:
  • @Cacheable  :应用到读取数据的方法上,即可缓存的方法,如查找方法:先从缓存中读取,如果没有再调用方法获取数据,然后把数据添加到缓存中
  • @CacheEvict :即应用到移除数据的方法上,如删除方法,调用方法时会从缓存中移除相应的数据
  • @CachePut   :应用到写数据的方法上,如新增/修改方法,调用方法时会自动把相应的数据放入缓存
  • @Caching    :上面三种注解配置方法时,一个方法只能使用三者之一。如果要使用多个,则需要使用@Caching
 
在查询的方法上使用缓存:
@Cacheable(value="platform.config" )
public String querySingleConfigValue(String configKey) {
指定key的生成规则:
@Cacheable(value="platform.config", key="#configKey")
public String querySingleConfigValue(String configKey) {
 
 
缓存的key的生成:

如果在Cache注解上没有指定key的话,会使用KeyGenerator生成一个key,默认提供了DefaultKeyGenerator生成器(Spring4之后使用SimpleKeyGenerator)。
如果只有一个参数,就使用该参数作为key,否则使用SimpleKey作为key,比如有两个入参,那么key将是这样的形式:SimpleKey [DEVELOPER_NAME,chenfeng]
可以在Cache注解上指定key的生成规则,通过SpEL表达式指定规则。详细可以参考:Spring Cache抽象详解
如果没有入参,又没有指定key,那么key将是“SimpleKey []”,这将很容易造成缓存的混乱,而且也不利于在更新的时候进行缓存的更新或移除

下面的代码入参是:SimpleKey []
@Cacheable (value = PlatformPrivateConstants.CACHE_NAME_CONFIG)
public List<SystemConfig> queryAllSingleConfigs() {
 
下面的代码入参是:SimpleKey [DEVELOPER_NAME,chenfeng]
@Cacheable (value = PlatformPrivateConstants.CACHE_NAME_CONFIG )
public String querySingleConfigValue(String configKey, String defaultValue) {
 
 
在更新的方法上更新缓存:

@CachePut(value=PlatformPrivateConstants.CACHE_NAME_CONFIG, key="#config.configKey")
public SystemConfig updateConfig(SystemConfig config) {
 
通过"#config.configKey"指定以入参config对象的configKey属性值作为缓存的key。
更新的方法必须将要缓存的对象作为返回值,只有这个返回的对象才会放入缓存中,如果在返回值被返回之前篡改了其内部数据,也会被反映到缓存中。
 
 
指定正确的key以防止缓存混乱:

下面两个方法,前者通过configKey查询对象,后者通过configKey查询对象中的configValue属性值:
public SystemConfig querySingleConfig(String configKey) {
public String querySingleConfigValue(String configKey) {
 
如果不指定key,或者使用相同的key,比如:
@Cacheable(value="platform.config")
public SystemConfig querySingleConfig(String configKey) {
@Cacheable(value="platform.config")
public String querySingleConfigValue(String configKey) {
如果以"DEVELOPER_NAME"作为configKey分别调用这两个方法,那么,先调用哪个方法,则那个方法的返回值会以"DEVELOPER_NAME"作为key存入缓存中,此时调用这两个方法时都会从缓存中取得这个值。比如先调用了querySingleConfig方法,那么查询到的SystemConfig对象就会以"DEVELOPER_NAME"为key存入缓存中,然后调用querySingleConfigValue方法,因为仍会以"DEVELOPER_NAME"作为key从缓存中提取数据,这时就会从缓存中取得了刚才那个SystemConfig对象,却当作是字符串型的configValue属性值返回了。
 
所以必须为这两个方法指定不同的缓存key:
@Cacheable(value="platform.config", key = "#configKey.concat('_object'))
public SystemConfig querySingleConfig(String configKey) {
@Cacheable(value="platform.config")
public String querySingleConfigValue(String configKey) {
 
这样前者使用入参configKey值后接"_object"作为key,而后者使用入参configKey值为key,就不会相互覆盖了。
 
 
在更新的方法上同时更新多个缓存:

在查询时,可能通过id查询也可能通过name查询,这样在缓存中就存有两份数据,在更新的时候就必须同时更新这两份缓存。
@Cacheable(value="platform.config", key = "#configId)
public SystemConfig querySingleConfig(long configId) {
@Cacheable(value="platform.config", key = "#configKey)
public SystemConfig querySingleConfig(String configKey) {
 
通过@Caching注解组合多个@CachePut注解,从而在调用更新方法时同时更新多份缓存(以不同的key存在于缓存中)
@Caching(put={@CachePut(value="platform.config" , key="#config.configId"),
              @CachePut(value="platform.config" , key="#config.configKey" )})
public SystemConfig updateConfig(SystemConfig config) {
 
 
 
在更新方法上同时更新和清除缓存:

上面的方法虽然可以同时更新多个缓存,但是必须保证这些缓存的值是完全一样的,比如上面两个方法缓存的都是SystemConfig对象,而对于下面的方法就无能为力了,因为下面的方法缓存的是SystemConfig对象的configValue属性值,而上面的方式只能把作为返回值的SystemConfig对象更新到缓存中。
@Cacheable(value="platform.config")
public String querySingleConfigValue(String configKey) {
 
对于这种情况,通过@CacheEvict清除那些无法更新的缓存,这样下次获取不到这些缓存就会越过缓存从数据库查询最新的数据。
@Caching(evict={@CacheEvict(value="platform.config", key="#config.configKey" )},
         put={@CachePut(value="platform.config", key="#config.configId.concat('_object')"),
              @CachePut(value="platform.config", key="#config.configKey.concat('_object')" )})
public SystemConfig updateConfig(SystemConfig config) {
 
 
 
使用缓存的业务层的设计宗旨:

使用缓存的业务类应尽量精简、方法应尽可能少,只保留最紧要的方法。
因为进行更新操作时需要考虑每一个的获取数据的方法,必须将可能被更新操作波及的所有缓存进行更新或清除,如果获取数据的方法过多,这个工作量将变得很大,并且很容易出错,比如忘记了更新或清除某一份缓存,而大型项目中这种错误可能难以被发现。另外,保存多份缓存,也增加了ehcache的负担,因为它需要维护这些缓存数据,比如需要判断哪些缓存最久未使用而从缓存中移除等。
所以应该在处于低层的业务类上使用缓存,而在高层的业务类上提供丰富的获取数据的方法,高层业务类所有操作均调用底层的业务类实现。
对于不会被频繁调用的方法,不要进行缓存,没有实际意义,还无谓增大ehcache的负担,并且浪费宝贵的内存。
4
1
分享到:
评论

相关推荐

    spring boot 相关技术

    5. **缓存**:讲解如何使用 Redis 或 Ehcache 等缓存技术优化性能。 6. **性能调优**:提供关于如何分析和优化 Spring Boot 应用性能的技巧。 《深入实践 Spring Boot》可能涉及更多高级和实践性的话题: 1. **...

    spring 4.1.5

    6. **缓存抽象**:Spring 4.1.5提供了统一的缓存抽象,支持包括 EhCache、Hazelcast 和 Infinispan 在内的多种缓存机制,简化了缓存的管理和使用。 7. **Spring Expression Language (SpEL) 改进**:Spring的表达式...

    整合Spring SpringMvc Mybatis,搭建SSM框架所用到jar包

    Mybatis通过XML或注解方式配置和映射原生信息,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。 整合SSM框架,首先需要确保正确地导入以下jar包: 1. **Spring核心库**:如...

    SSH最新框架整合(经典不容错过)

    3. **事务管理**: SSH整合中,通常使用Spring的声明式事务管理,通过`@Transactional`注解在方法级别声明事务边界,由Spring自动进行事务的开启、提交或回滚。 4. **整合中的拦截器**: 在Struts2中,可以利用拦截器...

    Hibernate二级缓存+分页功能

    Hibernate二级缓存通过插件实现,其中Ehcache是最常用的二级缓存实现。 二级缓存的配置主要包括以下步骤: 1. 引入Ehcache依赖。 2. 配置hibernate.cfg.xml,启用二级缓存并指定Ehcache配置文件。 3. 在实体类上...

    韩顺平spring 雇员管理系统hibernate jar包

    5. **Spring与Hibernate整合**:Spring提供了HibernateTemplate和HibernateDaoSupport等工具类,简化了Hibernate的使用。通过@Autowired或XML配置,可以将SessionFactory注入到DAO或Service类中,实现依赖注入。 6....

    Java Springboot入门自学笔记

    - 整合Redis、Ehcache等实现数据缓存。 - 使用`@Cacheable`、`@CacheEvict`等注解进行缓存操作。 #### 3.6 分页查询 - 使用Pageable接口和Spring Data JPA实现分页查询。 - 整合MyBatis-Plus进行高效数据库操作。 ...

    [springboot]Spring.pdf

    6. **无 XML 配置**:Spring Boot 强调简洁,避免过多的 XML 配置,主要使用注解驱动的编程模型。 【实战应用】 1. **Web 开发**:Spring Boot 可以轻松创建 RESTful API,结合 Spring MVC 和 Thymeleaf 等模板...

    Spring Boot 视频

    7. **缓存管理**:学习 Spring Boot 中的缓存支持,如 EhCache 或 Redis,以及如何在服务中实现缓存。 8. **安全控制**:掌握 Spring Security 的基本用法,包括身份验证(Authentication)、授权(Authorization)...

    hibernate,Spring所需基本jar包.

    1. **实体类和映射文件**:Hibernate通过XML或注解方式将Java类映射到数据库表,实体类代表数据库中的记录,映射文件或注解定义了类与表之间的关系。 2. **SessionFactory和Session**:SessionFactory是线程安全的...

    springbootapi

    14. **缓存管理**:Spring Boot支持EhCache、Hazelcast、Infinispan等多种缓存机制,提高应用性能。 15. **日志处理**:Spring Boot集成了各种日志框架,如Logback和Log4j2,提供灵活的日志配置。 《springboot大...

    springboot经典资源2

    12. **缓存机制**:Spring Boot支持各种缓存技术,如Ehcache、Hazelcast、Infinispan等,可以显著提升应用性能。 13. **云原生**:Spring Boot与Docker、Kubernetes等云原生技术结合,可以构建可扩展、可移植的...

    boot-jpa:Spring Boot 整合JPA

    - Native SQL查询:当需要使用数据库特定功能时,可以通过`@Query`注解写原生SQL。 8. **性能优化** - 一级缓存:JPA的EntityManager内部有缓存机制,同一个事务内多次读取同一对象,不会每次都去数据库查询。 -...

    SpringSide4 参考手册

    接着,文档详细介绍了如何在SpringSide中使用各种数据访问技术,包括Spring Data JPA、MyBatis以及原生JPA。这些部分讲述了如何进行动态组合查询条件、使用Hibernate二级缓存、以及如何配置数据源和事务管理。 为了...

    SSM毕业论文外文文献翻译.zip

    例如,优化方面可能包括了缓存策略的使用,如Spring的缓存抽象和EhCache的集成,以及Struts2的拦截器优化。事务管理是企业级应用的关键,Spring的声明式事务管理可以很好地解决这个问题。安全性方面,可能涉及了如何...

    hibernate参考文档

    ### Hibernate与Spring整合 在Spring框架中,可以使用HibernateTemplate或SessionFactory的代理类进行事务管理,同时Spring Data JPA提供了更高级别的Repository接口,简化了ORM操作。 总结,Hibernate作为Java领域...

    Springboot学习教程,Springboot精讲42课

    5. **缓存管理**:学习使用EhCache、Redis等实现应用的缓存功能。 6. **集成测试**:讲解如何编写和执行SpringBoot应用的单元测试和集成测试,利用JUnit和Mockito等工具。 7. **Actuator**:了解SpringBoot的监控...

    hibernate(notes)

    声明式事务管理通常结合Spring框架,通过@Transactional注解在方法级别声明事务边界。 八、性能优化 1. 避免N+1查询问题:通过批处理或JOIN查询减少数据库访问次数。 2. 使用HQL/JPQL:相比原生SQL,它们能更好地...

    Hibernate 高级特性

    使用第三方缓存提供商如EhCache,增加系统的响应速度,但需要注意并发控制和数据一致性问题。 二、 异步操作与批处理 1. 异步操作:通过集成Quartz或Spring的TaskExecutor,可以实现Hibernate操作的异步化,提高...

    hibernate-release-4.3.8.Final

    Hibernate内置了二级缓存,通过配置可使用EhCache等第三方缓存,提高数据访问效率。一级缓存为Session级别的缓存,二级缓存为SessionFactory级别的缓存。 8. **事务与异常处理** Hibernate提供事务管理接口,支持...

Global site tag (gtag.js) - Google Analytics