Spring AOP 实践(四)利用annotation实现声明式服务
来源:互联网 发布:solr remove node 编辑:程序博客网 时间:2024/06/03 17:26
上一篇中说到Spring AOP的一个重要作用是提供声明式企业服务,比如著名的声明式事务处理。
声明式企业服务真的很诱人,可以少写很多代码啊!就好像一句魔法就可以搞定一切。
AOP中可以用annotation来作为切入点的判断条件,比如@Transactional作为切入点,凡是声明了这个注解的方法都会被应用到事务处理的advice。今天我要用annotation和AOP来实现缓存的读取和存储,即在访问目标方法前先判断是否有缓存,有则返回,无则调用目标方法,在返回前存储缓存。
先来定义Annotation:
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface CacheRetrive {String cacheName() default "";String key();}
再定义一个消除缓存的注解:
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface CacheClear {String cacheName() default "";String[] keys();}不同的是keys是个数组,即可以清楚多个缓存项。
这是一个在保留到运行时的注解,目标对象是方法。有两个参数,一个是Cache的名字,cacheName,在这篇中不打算使用这个参数,给它一个默认值,否则不传值会报错。另外一个参数是key,就是要处理的缓存项目的key。
Aspect的定义:
@Aspect@Component public class RequestCacheAspect {private static Logger logger = Logger.getRootLogger();@Autowiredprivate EhcacheStorageManager cacheManager;@Around(value="execution(* com.viking.renting.service.*.*(..)) && @annotation(cacheRetrive)")public Object retriveFromCache(ProceedingJoinPoint pjp, CacheRetrive cacheRetrive) throws Throwable {String cacheKey = cacheRetrive.key();Object cacheValue = cacheManager.retrive(cacheKey);if(cacheValue != null) {logger.info("return from cache, key:" + cacheKey);return cacheValue;}Object retVal = pjp.proceed();cacheManager.save(cacheKey, retVal);logger.info("save to cache, key:" + cacheKey);return retVal;}@After(value="execution(* com.viking.renting.service.*.*(..)) && @annotation(cacheClear)")public void retriveFromCache(CacheClear cacheClear) throws Throwable {String[] keys = cacheClear.keys();for(String key: keys) {cacheManager.remove(key);logger.info("remove from cache, key:" + key);}}}从上面的代码可以看出注解的使用非常方便,可以直接把注解当作参数传进这个方法。第一个方法使用了@Around,就跟自己写个代理类的方法一样,不同的是这个方法可以应用到多个方法上,而我们只需要写一遍。这就是抽象的好处,把相同的事情抽象出来,只做一遍。第二个方法用了@After,在方法执行完成后调用清楚缓存的方法。下面是具体的调用:
<span style="white-space:pre"></span>@Transactional@CacheClear(keys="users_all")public User saveUser(User user) {....}
@Transactional(readOnly = true)@CacheRetrive(key="users_all")public List<UserTableDataDTO> fetchUsers() {return userDao.findUsers();}
在新增,修改和删除的方法上调用清除缓存,而在查询方法上调用@CacheRetrive。
这个注解放在DAO层是最好的。这只是一个简单的实现,更复杂的功能也是可以实现的。
0 0
- Spring AOP 实践(四)利用annotation实现声明式服务
- spring AOP annotation 实现日志服务
- 利用spring AOP和Annotation来简化DAO实现
- 利用spring AOP和Annotation来简化DAO实现
- 【Spring 基础篇四】annotation+aspectj实现AOP
- Spring Aop实现声明式事务
- Spring aop实现声明式事务
- Spring AOP的annotation实现
- Spring annotation 实现AOP逻辑
- annotation方式实现spring aop
- 利用Annotation方式实现AOP编程
- 利用Annotation和Aop实现日志记录
- Spring声明式事务管理,通过Spring AOP实现
- Spring声明式事务管理,通过Spring AOP实现
- Spring中AOP基于Annotation配置常用声明
- Spring原理(四)AOP的实现
- 利用Java Annotation 和 Spring AOP实现在Controller层面的操作日志记录
- Spring的AOP的annotation实现
- Rocketmq 文件名、msgId 生成规则
- 感知机学习算法的简单实现(Python)
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
- 指向常对象的指针变量和指向对象的常指针
- 51nod-【1003 阶乘后面0的数量】
- Spring AOP 实践(四)利用annotation实现声明式服务
- mac+eclipse 无法用debug正常启动
- [CF]-Continued Fractions
- RasSetAutodialEnable
- Mybatis中传入值,只传入list集合或者数组或者map操作
- 属性动画与图片三级缓存
- ***分解定理
- php中的filesize函数使用细节
- Lightoj1008