首页 > 程序开发 > 软件开发 > 其他 > 正文
Spring整合EhCache注解方式
2017-02-17 09:25:35       个评论    来源:poorCoder_的博客  
收藏    我要投稿

Spring整合EhCache注解方式:本文spring4通过注解方式 整合EhCache。同时提供xml注解方式和java配置的方式整合的源码

主要了解对数据缓存的增加、缓存的更新和缓存的删除。阅读之前需要先了解spring cache相关注解的介绍。请移步http://blog.csdn.net/poorCoder_/article/details/55258253。

maven 配置


  4.0.0
  com.test
  ehcahe2
  0.0.1-SNAPSHOT
  jar
  

    
          
        4.3.5.RELEASE  
        4.12
   
    
        
        
            org.springframework
            spring-core
            ${spring.version}
        
        
            org.springframework
            spring-context
            ${spring.version}
        
        
            org.springframework
            spring-context-support
            ${spring.version}
        
        
            org.springframework
            spring-aop
            ${spring.version}
        
          
            org.springframework  
            spring-jdbc  
            ${spring.version}  
        
          
            org.springframework  
            spring-web  
            ${spring.version}  
        
          
            org.springframework  
            spring-webmvc  
            ${spring.version}  
         
           
            org.springframework  
            spring-tx  
            ${spring.version}  
          


        
        
            junit
            junit
            ${junit.version}
            test
        

        
        
            org.springframework
            spring-test
            ${spring.version}
            test
        

        
        
            net.sf.ehcache
            ehcache
            2.7.5
        

           
        
            org.mybatis
            mybatis
            3.2.8
         
          
          
            org.mybatis  
            mybatis-spring  
            1.2.2  
          

          
        
            mysql
            mysql-connector-java
            5.1.27
            jar
            compile
        

          
          
            commons-dbcp  
            commons-dbcp  
            1.2.2  
        

            

         
            
                org.slf4j
                slf4j-api
                1.7.18
            
            

            
            
                org.slf4j
                slf4j-log4j12
                1.7.18
            
            

            
            
                org.apache.logging.log4j
                log4j-core
                2.5
            
            

     

ehcache.xml



         
       
    

     

实体类

实体类必须要序列化

public class User implements Serializable {

    private static final long serialVersionUID = 5272436524920090884L;
    private Integer id;
    private String name;
    //setter()  getter()...
    }

service接口:

package com.test.service;

import com.test.model.User;

public interface UserService {
    public User findUserById(int id);
    public void addUser(User user);
    public User updateUser(User user);
    public int countUser();

    public String getTimestamp(String param);
}

service实现类:

package com.test.service.impl;

import javax.annotation.Resource;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.test.dao.UserDao;
import com.test.model.User;
import com.test.service.UserService;

@Service("userService")
public class UserServiceImpl implements UserService{
    @Resource
    private UserDao userDao;

    /**
     * @Cacheable 将结果加入缓存。下次调用时直接从缓存中读取
     * cacheNames指定缓存,要与ehcache.xml中的cache明显相同
     */
    @Override
    @Cacheable(cacheNames="myCache",key="#id")
    public User findUserById(int id) {
        return userDao.findById(id);
    }

    /**
     * @CacheEvict 删除缓存
     * beforeInvocation=true 表示在方法执行之前删除缓存
     * 默认的 key=0 与下面 countUser()方法中key 相同
     */
    @Override
    @CacheEvict(cacheNames="myCache",key="0",beforeInvocation=true)
    public void addUser(User user) {
        userDao.add(user);
    }

    /**
     * @CachePut更新缓存
     * 将结果根据key 更新缓存中的内容
     */
    @Override
    @CachePut(cacheNames="myCache",key="#user.id")
    public User updateUser(User user) {
        userDao.update(user);
        return userDao.findById(user.getId());
    }

    @Override
    @Cacheable(cacheNames="myCache",key="0")
    public int countUser() {
        return userDao.count();
    }

    @Cacheable(cacheNames="myCache",key="#param")
    @Override
    public String getTimestamp(String param) {
        Long timestamp = System.currentTimeMillis();
        return timestamp.toString();
    }

}

配置

xml 配置形式


      
     
      
          
      

      
        
        
      

java类配置形式:

package com.test.config;

import org.apache.log4j.Logger;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

@Configuration  
@EnableCaching// 
public class CachingConfig {

     private static final Logger logger = Logger.getLogger(CachingConfig.class);  

    @Bean  
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {  
        EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();  
        ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource(  
                "ehcache.xml"));  
        return ehCacheManagerFactoryBean;  
    }  

    @Bean  
    public CacheManager cacheManager() {  
        logger.info("EhCacheCacheManager"); 
        EhCacheCacheManager cacheManager = new EhCacheCacheManager();  
        cacheManager.setCacheManager(ehCacheManagerFactoryBean().getObject());  
        return cacheManager;  
    }  
}

测试

基类:

package com.test.baseTest;

import org.junit.runner.RunWith;  
import org.springframework.test.context.ContextConfiguration;  
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;  
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  

import com.test.config.AppConfig;
import com.test.config.DatabaseConfig;
//XML配置
//@ContextConfiguration(locations = { "classpath:applicationContext.xml" })  
//java类配置
@ContextConfiguration(classes = {AppConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)  
public class SpringTestCase extends AbstractJUnit4SpringContextTests {

}

测试类:

package com.test.testService;

import javax.annotation.Resource;

import org.junit.Test;

import com.test.baseTest.SpringTestCase;
import com.test.model.User;
import com.test.service.UserService;

public class TestService extends SpringTestCase {

    @Resource
    private UserService userService;

    @Test
    public void addUser(){
        User user = new User();
        user.setName("李四");
        userService.addUser(user);
    }

    @Test
    public void testQuery() throws InterruptedException{
        System.out.println("第一次调用");
        System.out.println( userService.findUserById(1));
        System.out.println("第二次调用");
        System.out.println(userService.findUserById(1));

    }
    @Test
    public void testUpdate(){
        User user = userService.findUserById(1);
        System.out.println( "第一次调用"+user);
        user.setName(user.getName()+"1");
        userService.updateUser(user);
        System.out.println("第二次调用"+userService.findUserById(1));
    }

    @Test
    public void testCount(){
        System.out.println("第一次查询数量:"+userService.countUser());
        addUser();
        System.out.println("第二次查询数量:"+userService.countUser());
    }

    @Test  
    public void getTimestampTest() throws InterruptedException{  
        System.out.println("第一次调用:" + userService.getTimestamp("param"));
        Thread.sleep(2000);
        System.out.println("2秒之后调用:" + userService.getTimestamp("param"));
    } 

}

测试结果分析

调用testQuery()方法时结果为:
image
从结果来看:第一次调用时访问了数据库 并且将数据放入了缓存。第二次调用时,没有访问数据库就直接返回了,缓存生效。

调用testCount()方法返回结果为:

image
从结果中可以看出,第一次查询数量访问了数据库。并且将数据放入缓存。但是执行了addUser()之后.缓存中的数据又被清除了。

调用testUpdate()返会结果:
第一次调用返回信息,并放入缓存。中间调用更新用户信息后,将新的返回信息更到缓存中。第二次调用时,没有访问数据库,但返回的数据是新的。

JDBC Connection [jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false, UserName=root@localhost, MySQL Connector Java] will not be managed by Spring
[DEBUG] 2017-02-16 15:42:01,118 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139)
==>  Preparing: SELECT id,name FROM t_user WHERE id = ? 
[DEBUG] 2017-02-16 15:42:01,137 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139)
==> Parameters: 1(Integer)
[DEBUG] 2017-02-16 15:42:01,150 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139)
<==      Total: 1
[DEBUG] 2017-02-16 15:42:01,151 method:org.mybatis.spring.SqlSessionUtils.closeSqlSession(SqlSessionUtils.java:168)
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7463e563]
[DEBUG] 2017-02-16 15:42:01,151 method:org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:327)
Returning JDBC Connection to DataSource
[DEBUG] 2017-02-16 15:42:01,152 method:net.sf.ehcache.store.disk.Segment.put(Segment.java:432)
put added 0 on heap
第一次调用User [id=1, name=张三]
[DEBUG] 2017-02-16 15:42:01,156 method:org.springframework.cache.interceptor.AbstractFallbackCacheOperationSource.getCacheOperations(AbstractFallbackCacheOperationSource.java:97)
Adding cacheable method 'updateUser' with attribute: [Builder[public com.test.model.User com.test.service.impl.UserServiceImpl.updateUser(com.test.model.User)] caches=[myCache] | key='#user.id' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='']
[DEBUG] 2017-02-16 15:42:01,156 method:org.mybatis.spring.SqlSessionUtils.getSqlSession(SqlSessionUtils.java:104)
Creating a new SqlSession
[DEBUG] 2017-02-16 15:42:01,156 method:org.mybatis.spring.SqlSessionUtils.getSqlSession(SqlSessionUtils.java:140)
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1fd4340c] was not registered for synchronization because synchronization is not active
[DEBUG] 2017-02-16 15:42:01,156 method:org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:110)
Fetching JDBC Connection from DataSource
[DEBUG] 2017-02-16 15:42:01,157 method:net.sf.ehcache.store.disk.Segment.faultInternal(Segment.java:762)
fault removed 0 from heap
[DEBUG] 2017-02-16 15:42:01,157 method:org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:86)
JDBC Connection [jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false, UserName=root@localhost, MySQL Connector Java] will not be managed by Spring
[DEBUG] 2017-02-16 15:42:01,157 method:net.sf.ehcache.store.disk.Segment.faultInternal(Segment.java:774)
fault added 0 on disk
[DEBUG] 2017-02-16 15:42:01,157 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139)
==>  Preparing: UPDATE t_user SET name = ? WHERE id = ? 
[DEBUG] 2017-02-16 15:42:01,158 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139)
==> Parameters: 张三1(String), 1(Integer)
[DEBUG] 2017-02-16 15:42:01,186 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139)
<==    Updates: 1
[DEBUG] 2017-02-16 15:42:01,186 method:org.mybatis.spring.SqlSessionUtils.closeSqlSession(SqlSessionUtils.java:168)
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1fd4340c]
[DEBUG] 2017-02-16 15:42:01,187 method:org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:327)
Returning JDBC Connection to DataSource
[DEBUG] 2017-02-16 15:42:01,187 method:org.mybatis.spring.SqlSessionUtils.getSqlSession(SqlSessionUtils.java:104)
Creating a new SqlSession
[DEBUG] 2017-02-16 15:42:01,187 method:org.mybatis.spring.SqlSessionUtils.getSqlSession(SqlSessionUtils.java:140)
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@215b011c] was not registered for synchronization because synchronization is not active
[DEBUG] 2017-02-16 15:42:01,187 method:org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:110)
Fetching JDBC Connection from DataSource
[DEBUG] 2017-02-16 15:42:01,188 method:org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:86)
JDBC Connection [jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false, UserName=root@localhost, MySQL Connector Java] will not be managed by Spring
[DEBUG] 2017-02-16 15:42:01,188 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139)
==>  Preparing: SELECT id,name FROM t_user WHERE id = ? 
[DEBUG] 2017-02-16 15:42:01,188 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139)
==> Parameters: 1(Integer)
[DEBUG] 2017-02-16 15:42:01,189 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139)
<==      Total: 1
[DEBUG] 2017-02-16 15:42:01,189 method:org.mybatis.spring.SqlSessionUtils.closeSqlSession(SqlSessionUtils.java:168)
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@215b011c]
[DEBUG] 2017-02-16 15:42:01,189 method:org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:327)
Returning JDBC Connection to DataSource
[DEBUG] 2017-02-16 15:42:01,193 method:net.sf.ehcache.store.disk.Segment.put(Segment.java:432)
put added 0 on heap
[DEBUG] 2017-02-16 15:42:01,195 method:net.sf.ehcache.store.disk.Segment.put(Segment.java:460)
put updated, deleted 0 on heap
[DEBUG] 2017-02-16 15:42:01,195 method:net.sf.ehcache.store.disk.Segment.put(Segment.java:464)
put updated, deleted 0 on disk
[DEBUG] 2017-02-16 15:42:01,195 method:net.sf.ehcache.store.disk.Segment.faultInternal(Segment.java:762)
fault removed 0 from heap
[DEBUG] 2017-02-16 15:42:01,195 method:net.sf.ehcache.store.disk.Segment.faultInternal(Segment.java:774)
fault added 0 on disk
第二次调用User [id=1, name=张三1]

最后附上源码例子:
http://download.csdn.net/detail/poorcoder_/9755967

点击复制链接 与好友分享!回本站首页
上一篇:适配器模式
下一篇:@WSDLDocumentation WebService 客户端中文乱码
相关文章
图文推荐
文章
推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做实用的IT技术学习网站