spring aop 的一个demo(未完,待完善)
假设我们有这样的一个场景 : 对于一个类的众多方法,有些方法需要从缓存读取数据,有些则需要直接从数据库读取数据。怎样实现呢?
实现方案有多种。下面我说下常见的几种实现方案 :
1、直接采用spring xml、或者 annotation AOP完成。但个人认为这种方案似乎有点不是很完美。
原因 : ①、如果只有针对这个类做切面拦截,这种方案是没有问题的,只需对需要走DB(or 缓存,两者择一)的方法配置切面。
②、那如果是多个类呢?统一做一个切面,对指定方法拦截,如selectXXX。但,还要考虑个特殊场景,每个人的代码风格不一致,你不能限制
别人的风格,查询他就偏偏用queryXXX来命令。你能拦截到么?
2、采用 ProxyFactory 拦截处理, 并且用java自定义的annotation来作为是否需要走缓存的方法唯一标识。(实现得不是很好,后期会持续优化,见谅)
看下代码
1)自定义注解,标识是否需要走缓存
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheAnnotition { }
2)接口定义
public interface UserReadService {
@CacheAnnotition
public UserInfo getUserInfoById(Long id);
public UserInfo getUserInfoByName(String name);
}
@Component("userReadService")
public class UserReadServiceImpl implements UserReadService {
@Override
public UserInfo getUserInfoById(Long id) {
System.out.println("获取用户信息");
return null;
}
@Override
public UserInfo getUserInfoByName(String name) {
// TODO Auto-generated method stub
return null;
}
}
public interface PeopleReadService {
@CacheAnnotition
public UserInfo getPeopleInfoById(Long id);
public UserInfo getPeopleInfoByName(String name);
}
@Component("peopleReadService")
public class PeopleReadServiceImpl implements PeopleReadService {
@Override
public UserInfo getPeopleInfoById(Long id) {
System.out.println("getPeopleInfoById : 获取用户信息");
return null;
}
@Override
public UserInfo getPeopleInfoByName(String name) {
// TODO Auto-generated method stub
return null;
}
}
3)拦截处理核心逻辑
public class ProxyFactoryDemo {
public static Map<String, Class<?>> beanMap = new HashMap<String, Class<?>>();
public static Map<String, Class<?>> instanceMap = new HashMap<String, Class<?>>();
public static List<Object> proxyObjs = new ArrayList<Object>();
static {
beanMap.put("userReadService", UserReadService.class);
beanMap.put("peopleReadService", PeopleReadService.class);
instanceMap.put("userReadService", UserReadServiceImpl.class);
instanceMap.put("peopleReadService", PeopleReadServiceImpl.class);
}
public static void main(String[] args) throws Exception {
initProxyObjs();
for(Object proxy : proxyObjs) {
if (proxy instanceof UserReadService) {
UserReadService u = (UserReadService)proxy;
u.getUserInfoById(null);
u.getUserInfoByName(null);
} else if(proxy instanceof PeopleReadService) {
PeopleReadService p = (PeopleReadService)proxy;
p.getPeopleInfoById(null);
p.getPeopleInfoByName(null);
}
}
}
public static void initProxyObjs() throws InstantiationException, IllegalAccessException {
Iterator<String> it = beanMap.keySet().iterator();
while (it.hasNext()) {
String beanName = it.next();
Class<?> beanClass = instanceMap.get(beanName);
Object proxy = getProxy(beanClass.newInstance(), beanMap.get(beanName), beanName);
proxyObjs.add(proxy);
}
}
public static Object getProxy(final Object target, Class<?> aClass, final String beanName) {
ProxyFactory factory = new ProxyFactory();
factory.addInterface(aClass);
factory.setTarget(target);
factory.setOpaque(true);
factory.addAdvice(new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("start");
if (invocation.getMethod().isAnnotationPresent(CacheAnnotition.class)) {
System.out.println(invocation.getMethod().getName() + "需要走缓存");
} else {
System.out.println(invocation.getMethod().getName() + "不需要走缓存");
}
Object obj = invocation.proceed();
System.out.println("end");
return obj;
}
});
return factory.getProxy(factory.getClass().getClassLoader());
}
}
spring aop 的一个demo(未完,待完善)的更多相关文章
- spring Aop的一个demo
面向切面是什么我就不说了. 上代码: package com.foreveross.service.weixin.test; import java.lang.annotation.Documente ...
- 运用Spring Aop,一个注解实现日志记录
运用Spring Aop,一个注解实现日志记录 1. 介绍 我们都知道Spring框架的两大特性分别是 IOC (控制反转)和 AOP (面向切面),这个是每一个Spring学习视频里面一开始都会提到 ...
- Spring AOP应用实例demo
AOP(Aspect-Oriented Programming.面向方面编程).能够说是OOP(Object-OrientedPrograming.面向对象编程)的补充和完好.OOP引入封装.继承和多 ...
- spring aop 的一个思考
问题: spring aop 默认使用jdk代理织入. 也就是我们常这样配置:<aop:aspectj-autoproxy /> 通过aop命名空间的<aop:aspectj-au ...
- SSH框架系列:Spring AOP应用记录日志Demo
分类: [java]2013-12-10 18:53 724人阅读 评论(0) 收藏 举报 1.简介 Spring 中的AOP为Aspect Oriented Programming的缩写,面向切面编 ...
- Spring aop 小例子demo
由于最近的服务项目提供接口有一个需求,所有操作都必须检查操作的服务可用,所以感觉Aop特别适合实施.完成学习的小例子. 关于spring-Aop原理:http://m.oschina.net/blog ...
- Spring AOP的一个简单实现
针对学习笔记(六)中的购买以及退货代码,我们加入AOP框架,实现同样一个功能. 首先配置XML:service采用和之前一样的代码,只是没有通过实现接口来实现,而是直接一个实现类.transactio ...
- Spring Boot 第一个demo
Sring boot 一直没有使用过,跳槽来到新公司,暂时没有事情就学习一下. Spring boot 这里采用的是maven 来创建的 maven项目的pom.xml 文件 <?xml v ...
- Spring IoC容器总结(未完)
在面向对象系统中,对象封装了数据和对数据的处理,对象的依赖关系常常体现在对数据和方法的依赖上.这些依赖关系可以通过把对象的依赖注入交给框架或IOC容器来完成,这种从具体对象手中交出控制的做法是非常有价 ...
随机推荐
- Android 签名(7)签名常见问题,debug签名和release签名的区别等
一般在安装时提示出错:INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES 1) 两个应用,名字相同,签名不同 2) 升级时前一版本签名,后一版本没签名 3) ...
- Hibernate映射之实体映射<转载>
实体类与数据库之间存在某种映射关系,Hibernate依据这种映射关系完成数据的存取,因此映射关系的配置在Hibernate中是最关键的.Hibernate支持xml配置文件与@注解配置两种方式.xm ...
- poj 1860 Currency Exchange (最短路bellman_ford思想找正权环 最长路)
感觉最短路好神奇呀,刚开始我都 没想到用最短路 题目:http://poj.org/problem?id=1860 题意:有多种从a到b的汇率,在你汇钱的过程中还需要支付手续费,那么你所得的钱是 mo ...
- 函数buf_LRU_search_and_free_block
/******************************************************************//** Try to free a replaceable bl ...
- 通用权限管理系统Ver2.0
通用权限管理系统Ver2.0平台采用kendo+mvc4+Nhibernate技术实现,底层采用自定义ORM实现数据库底层代码,支持Oracle.SqlServer.mysql等常用数据库,界面采用k ...
- Jquery AutoComplete的使用方法实例
jquery.autocomplete详解 语法: autocomplete(urlor data, [options] ) 参数: url or data:数组或者url [options]:可选项 ...
- u-boot向linux内核传递启动参数(详细)
U-BOOT 在启动内核时,会向内核传递一些参数.BootLoader 可以通过两种方法传递参数给内核,一种是旧的参数结构方式(parameter_struct),主要是 2.6 之前的内核使用的方式 ...
- 2、Android应用程序基本特性
1. apk是android应用程序安装格式,.dex是Android二进制执行文件格式. 2.Android操作系统是基于Linux的多用户操作系统,每一个应用程序都是使用的不同的用户. 3. 默认 ...
- HDU 4825-Xor Sum(trie)
题意: 给你一组数,开始询问给一个数 求组中与该数异或值最大的数. 分析:根据异或的特点 要想得到的异或值最大 尽可能的让两个数的每位都相反 先把给定的一组数建树,数的最后一位对应的节点保存这个数的 ...
- LeetCode题解——Longest Palindromic Substring
题目: 给定一个字符串S,返回S中最长的回文子串.S最长为1000,且最长回文子串是唯一. 解法: ①遍历,对于每个字符,计算以它为中心的回文子串长度(长度为奇数),同时计算以它和右边相邻字符为中心的 ...