/**增量包装类*/
public class IncrementDO<T> implements Serializable {
private static final long serialVersionUID = -6615881328594646517L;
/** 删除数据列表 **/
private final List<T> deletedList;
/** 增加数据列表 **/
private final List<T> addedList;
/** 时间戳 **/
private final Long timestamp;
public IncrementDO(List<T> deletedList, List<T> addedList, Long timestamp) {
super();
this.deletedList = deletedList;
this.addedList = addedList;
this.timestamp = timestamp;
}
public List<T> getDeletedList() {
return deletedList;
}
public List<T> getAddedList() {
return addedList;
}
public Long getTimestamp() {
return timestamp;
}
@Override
public String toString() {
return "IncrementDO[deletedList=" + deletedList.size() + ", addedList=" +
addedList.size() + ", timestamp=" + timestamp + "]";
}
}/**Annotation*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LocalIncreaCacheOperation {
}public interface ConfigService {
/**用户拥有在timeStamp之前的正确数据,用户将调用这个接口*/
public IncrementDO<Long> getIncrementUserIds(long timeStamp)
throws ServiceException;
}
public class ConfigServiceImpl implements ConfigService {
UserManager userManager;
public IncrementDO<Long> getIncrementUserIds(long timeStamp)
throws ServiceException{
if(timeStamp < 0) {
throw new ServiceException("timestamp is wrong");
}
try{
long ts = this.userManager.getDBTimestamp(); // db 当前时间戳
return this.getIncrementUserIds(timeStamp,ts);
} catch (ManagerException e) {
throw new ServiceException(e);
}
}
/**
* 增量缓存的辅助接口,AOP将拦截这个接口
*/
@LocalIncreaCacheOperation
public IncrementDO<Long> getIncrementUserIds(long beginTimesStamp,
Long endTimesStamp) throws ServiceException{
try{
IncrementDO<Long> result = null;
List<Long> addList = this.userManager.getAddedUserIds(
beginTimesStamp, endTimesStamp);
List<Long> deletedList = this.userManager.getDeletedUserIds(
beginTimesStamp, endTimesStamp);
result = new IncrementDO<Long>(deletedList, addList, endTimesStamp);
return result;
}catch(ManagerException e) {
throw new ServiceException(e);
}
}
}/**ibatis sql,用STATUS=1表示数据有效,STATUS=99表示数据已删除*/
<select id="getAddedUserIds" resultClass="java.lang.Long"
parameterClass="java.util.Map">
<![CDATA[
SELECT USER_ID
FROM user
WHERE GMT_MODIFIED >= #begin# and
GMT_MODIFIED <= #end# and STATUS = 1
]]>
</select>
<select id="getDeletededUserIds" resultClass="java.lang.Long"
parameterClass="java.util.Map">
.....
</select>/**
* 核心切面实现
*/
@Aspect
public class LocalIncreaCacheAspect {
private LocalCache localCache;
@Around("execution(@LocalIncreaCacheOperation * *(..))")
public Object doCache(ProceedingJoinPoint pjpParam) throws Throwable {
final ProceedingJoinPoint pjp = pjpParam;
Signature sig = pjp.getSignature();
if (sig instanceof MethodSignature) {
MethodSignature mSig = (MethodSignature) sig;
String localCacheKey = mSig.getName();
Long beginTimesStamp = (Long) pjp.getArgs()[0];
Long endTimesStamp = (Long) pjp.getArgs()[1];
Calendar reqTime = Calendar.getInstance(); // 请求时间
reqTime.setTime(new Date(beginTimesStamp));
reqTime.set(reqTime.get(Calendar.YEAR),
reqTime.get(Calendar.MONTH),
reqTime.get(Calendar.DAY_OF_MONTH),
reqTime.get(Calendar.HOUR_OF_DAY),
reqTime.get(Calendar.MINUTE), 0); // 秒清零
Calendar curTime = Calendar.getInstance(); // db当前时间
curTime.setTime(new Date(endTimesStamp));
curTime.set(curTime.get(Calendar.YEAR),
curTime.get(Calendar.MONTH),
curTime.get(Calendar.DAY_OF_MONTH),
curTime.get(Calendar.HOUR_OF_DAY),
curTime.get(Calendar.MINUTE), 0); // 秒清零
long diffTime = curTime.getTimeInMillis()
- reqTime.getTimeInMillis();
if (diffTime < 0) {
throw new ServiceException("timestamp is wrong");
}
IncrementDO<Long> tmp;
Set<Long> add = new HashSet<Long>();
Set<Long> del = new HashSet<Long>();
long minCount = diffTime / (60 * 1000); // 相差分钟数
for (long i = 0; i < minCount; i++) { // 遍历相差的分钟数
tmp = null;
tmp = (IncrementDO<Long>) localCache.get(localCacheKey + "_"
+ reqTime.getTimeInMillis() + "_"
+ (reqTime.getTimeInMillis() + 60000));
if (tmp == null) {
tmp = (IncrementDO<Long>) pjp.proceed(new Object[] {
reqTime.getTimeInMillis(),
reqTime.getTimeInMillis() + 60000 });
localCache.put(localCacheKey + "_"
+ reqTime.getTimeInMillis() + "_"
+ (reqTime.getTimeInMillis() + 60000), tmp);
}
if (tmp != null) {
del.removeAll(tmp.getAddedList());
add.addAll(tmp.getAddedList());
add.removeAll(tmp.getDeletedList());
del.addAll(tmp.getDeletedList());
}
reqTime.add(Calendar.MINUTE, 1);
}
IncrementDO<Long> result = new IncrementDO<Long>(
new ArrayList<Long>(del), new ArrayList<Long>(add),
curTime.getTimeInMillis());
}
return pjp.proceed(pjp.getArgs());
}
}原文地址:http://blog.csdn.net/troy__/article/details/39527675