이번 포스팅에서는 예제에서 사용한 Redis 설정에 대해서 기술한다.
<?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:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="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-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">
<bean id="connectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="#{redisProp['hostName']}" />
<property name="port" value="#{redisProp['port']}" />
<property name="poolConfig" ref="jedisPoolConfig"></property>
</bean>
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="20"></property>
</bean>
<context:component-scan base-package="com.example.redis" />
<util:properties id="redisProp" location="classpath:/properties.xml" >
</util:properties>
</beans>
Util: properties 와 SpEL 사용방법
http://secondmemory.kr/271
Resources경로에 아래의 xml 프로퍼티를 추가하자.
192.168.0.105
8000
Method 정보를 저장하는 Dto 생성
package com.example.redis;
public class RankDto {
private int rank;
private String methodName;
private int callCount;
public int getRank() {
return this.rank;
}
public void setRank(int rank) {
this.rank = rank;
}
public String getMethodName() {
return this.methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public int getCallCount() {
return this.callCount;
}
public void setCallCount(int callCount) {
this.callCount = callCount;
}
}
호출되는 함수 Dto를 저장할 Repository 인터페이스
public abstract interface ActionHistoryRepo<Key, Value> {
public abstract void addAction(Value paramValue);
public abstract List<RankDto> getRank();
public abstract void deleteAction(Key paramKey);
}
Repository 인터페이스의 구현 클래스
이 예제에서는 실행되는 함수의 실행 횟수를 저장하고 통계를 내기 위해서 Redis Zset 타입을 이용하여 구현한다.
ZSet 사용법은 아래의 사이트를 참고하자
http://www.tutorialspoint.com/redis/redis_sorted_sets.htm
@Repository("actionHistory")
public class HistorySaver implements ActionHistoryRepo<String, String> {
//Redis ZSet을 사용하기 위한 고정키
private final String redisKey = "MethodRank";
@Autowired
private RedisTemplate<String, String> stringRedisTemplate;
public void addAction(String value) {
int score = 1;
// 개체가 없으면 자동으로 생성 한 후 스코어에 +1
this.stringRedisTemplate.opsForZSet().incrementScore("MethodRank",
value, score);
}
public List<RankDto> getRank() {
//Range를 사용하면 내림차순이 기본으로 설정된다. Reverse Range를 사용하여 오름차순 순서로 뽑아내자.
Set<String> rankset = this.stringRedisTemplate.opsForZSet()
.reverseRange(redisKey , 0L, -1L);
List<RankDto> rankList = new ArrayList();
Iterator<String> iters = rankset.iterator();
int ranky = 1;
while (iters.hasNext()) {
RankDto dto = new RankDto();
dto.setMethodName((String) iters.next());
Double rank = this.stringRedisTemplate.opsForZSet().score(
redisKey , dto.getMethodName());
dto.setCallCount(rank.intValue());
dto.setRank(ranky);
rankList.add(dto);
ranky++;
}
return rankList;
}
public void deleteAction(String key) {
this.stringRedisTemplate.delete(key);
}
}
구현된 결과물을 Tomcat was를 이용해서 실행해 보자.
http://localhost:8080/aop/act1

http://localhost:8080/aop/rank

소스코드 주소는 다음과 같다.
https://github.com/wargen99/wargen-repo.git
아주 간단하게 AOP를 이용하여 사이트 내의 서비스 메소드가 호출되는 통계를 저장하는 예제를 만들어 보았다.
아주 기초적인 예제지만 이를 응용하여 다양한 관점에서 데이터를 저장하고 이를 재활용할 수 있는 점을 확인하면 좋을 듯 하다.