Redis 를 활용해서 Cache를 적용해보자..


우선 Redis Client는 http://www.redis.io/clients 에서 확인되는바와 같이 종류가 여러가지다.

그런데 Spring Data Redis 를 사용하면 별도의 Client가 필요 없네...(Interface만 있고 구현체는 가져다 쓰는줄 알았더니 아니네요.)


Source Code에서 사용법과 Method Annotataion 사용법을 보자.


[build.gradle]

1
2
3
4
dependencies {
    compile springDependencies // Spring 3.2.x
    compile 'org.springframework.data:spring-data-redis:1.3.4.RELEASE'
}


[context-cache.xml]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<!--?xml version="1.0" encoding="UTF-8"?-->
  
    <cache:annotation-driven>
  
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="${redis.pool.maxTotal}">
        <property name="maxIdle" value="${redis.pool.maxIdle}">
        <property name="minIdle" value="${redis.pool.minIdle}">
    </property></property></property></bean>
  
    <bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="${redis.host}">
        <property name="port" value="${redis.port}">
        <property name="poolConfig" ref="jedisPoolConfig">
    </property></property></property></bean>
  
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="jedisConnFactory">
    </property></bean>
     
    <!-- 접두어(실제 키는 prefix:cacheName:key 가된다. -->
    <bean id="prefix" class="pe.kr.ddakker.core.framework.cache.prefix.RedisCacheNamePrefix">
        <constructor-arg name="delimiter" value="SAMPLE">
    </constructor-arg></bean>
  
    <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg name="template" ref="redisTemplate">
        <property name="usePrefix" value="true">
        <property name="cachePrefix" ref="prefix">
        <!-- 초 단위 -->
        <property name="expires">
            <map>
                <entry key="BANNER" value="60">
                <entry key="EVENT" value="5">
            </entry></entry></map>
        </property>
        <!-- 순서 중요!!! 맨 나중에!! -->
        <property name="cacheNames">
            <list>
                <value>BANNER</value>
                <value>EVENT</value>
            </list>
        </property>
    </property></property></constructor-arg></bean>
  
    <bean id="cacheEvent" class="pe.kr.ddakker.core.framework.cache.CacheRedis">
        <constructor-arg name="cacheManager" ref="cacheManager">
        <constructor-arg name="cacheName" value="EVENT">
    </constructor-arg></constructor-arg></bean>
  
    <bean id="cacheBanner" class="pe.kr.ddakker.core.framework.cachezCacheRedis">
        <constructor-arg name="cacheManager" ref="cacheManager">
        <constructor-arg name="cacheName" value="BANNER">
    </constructor-arg></constructor-arg></bean>
  
</cache:annotation-driven></beans>


[RedisTestCase.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath*:config/spring/context-common.xml",
        "classpath*:config/spring/context-cache.xml",
        "classpath*:config/spring/context-datasource.xml"
})
public class RedisTestCase {
    @Resource Cache<string> cacheEvent;
    @Resource Cache<user> cacheBanner;
  
    @Resource AuthService authService;
  
    @Test
    public void test() {
        User user = new User();
        user.setUserNm("ddakker");
      
        cacheEvent.put("a", "zzz");
        String a = cacheEvent.get("a");
        System.out.println("a: " + a);
      
        cacheBanner.put("user", user);
        User resultUser = cacheBanner.get("user");
        System.out.println("user: " + resultUser);
    }
  
}
  
@Test
public void testAnnotation() {
    // DB 쿼리 호출
    List<auth> authList = authService.getList();
    System.out.println("authList: " + authList);
  
    // DB 쿼리 호출 않음
    authList = authService.getList();
    System.out.println("authList: " + authList);
  
    Auth auth = new Auth();
    auth.setSearchKey("AUTH_CD");
    auth.setSearchKwd("ROLE_USER");
  
    // DB 쿼리 호출
    authList = authService.getList(auth);
    System.out.println("authList user: " + authList);
  
    // DB 쿼리 호출 않음
    authList = authService.getList(auth);
    System.out.println("authList user: " + authList);
}
</auth></user></string>


[AuthService.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// @Cacheable 의 key나 조건의 디테일한 제어에 대한 설멍은 - http://dev.anyframejava.org/docs/anyframe/plugin/optional/cache/1.0.3/reference/html/ch01.html
@Service
public class AuthService {
    @javax.annotation.Resource AuthMapper authMapper;
  
    @Cacheable(value="BANNER")
    public List<auth> getList() {
        return authMapper.getList(new Auth());
    }
  
    @Cacheable(value="EVENT")
    public List<auth> getList(Auth authVo) {
        return authMapper.getList(authVo);
    }
}
</auth></auth>

+ Recent posts