一般情況下,java程式取一條資料是直接從資料庫中去取,當資料庫達到一定的連接配接數時,就會處于排隊等待狀态, 某些在一定時間内不會發生變化的資料,完全沒必要每次都從資料庫中去取, 使用spring-aop + memcached 技術,取資料時,先從緩存中去取,緩存中如果存在,直接傳回結果,無需通路資料庫;如果緩存中不存在,再通路資料庫,并把這條資料儲存到緩存中,當程式下次再通路時,就可以取到緩存中的值了。這樣不但可以大大減少通路資料庫的次數(減輕資料的負擔),而且可以提高程式的運作效率,因為memecached 是采用key - value 方法存取資料的。
使用memcached時特别需要注意的是: 1.當某條資料發生變化時,一定要更新cache中的這條記錄; 2.設定key時一定要唯一, 一般是通過prefix + uuid 保證唯一,prefix一般使用資料庫的表名
下面來介紹一下spring-aop + memcached 技術的簡單實作:

1.定義注解類 @Cache
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cache {
/**
* key的字首
* @return
*/
String prefix();
/**
* 指定哪個參數值做Key,與cacheKey兩者選一,如果都有輸入,預設使用indexKey
* @return
*/
int indexKey() default 0;
/**
* 緩存有效期 1000*60*60*2=2小時
* @return
*/
long expiration() default 1000 * 60 * 60 * 2;
}
2.定義切入點類 CachePoint,這個類一定要與上面的注解類在同一包目錄下
@Component
@Aspect
public class CachePoint {
@Autowired
private CacheService cacheService;
/**
* @Pointcut("@annotation(Cache)") 表示定義切入點所有帶有@Cache注解的方法
*/
@Pointcut("@annotation(Cache)")
public void queryCache(){
System.out.println("此輸出将不會執行...");
}
@Around("queryCache()")
public Object getByCache(ProceedingJoinPoint pjp) throws Throwable {
// 1.查詢緩存的值
Object obj = cacheService.getKey("test_1000123456");
// 2.如果緩存中不存在,則查詢mysql資料庫
if (null==obj) {
obj = pjp.proceed();
// 3.将obj的值寫入緩存
cacheService.setKey("test_1000123456", obj);
}
return obj;
}
}
3.編寫memcached 的業務類
@Component("cacheService")
public class CacheService {
/**
* 讀取緩存的方法
* @param key
* @return
*/
public Object getKey(String key) {
System.out.println("query from memcached");
return null;
}
/**
* 寫入緩存的方法
* @param key
* @param obj
*/
public void setKey(String key, Object obj) {
}
/**
* 删除緩存的方法
* @param key
*/
public void delete(String key) {
}
}
4.Dao 的實作層添加注解
@Component("testDao")
public class TestDaoImpl implements TestDao {
/**
* 此處将使用 prefix + indexKey 作為緩存的key,即 test_ + uuid
*/
@Cache(indexKey=1, prefix="test_")
@Override
public String query(String uuid) {
System.out.println("query from mysql");
return "caoxiaobo";
}
}
配置檔案spring-aop.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 自動掃描 -->
<context:component-scan base-package="com.spring.*" />
<!-- 開啟注入注解掃描 -->
<context:annotation-config/>
<aop:aspectj-autoproxy/>
</bea
測試:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring-aop.xml" })
public class SprintAopAndCacheTest {
@Autowired
TestService testService;
@Test
public void test() {
String name = testService.query("1000123456");
System.out.println(name);
}
}