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容器来完成,这种从具体对象手中交出控制的做法是非常有价 ...
随机推荐
- Hbase二级索引
http://blog.sina.com.cn/s/blog_4a1f59bf01018apd.html
- openSession()和getCureentSession()的区别
openSession():永远是打开一个新的session getCureentSession():如果当前环境有session,则取得原来已经存在的session,如果没有,则创建一个新的sess ...
- sharepoint 2010 页面添加footer方法 custom footer for sharepoint 2010 master page
转:http://blog.csdn.net/chenxinxian/article/details/8720893 在sharepoint 2010的页面中,我们发现,没有页尾,如果我们需要给页面添 ...
- java jvm学习笔记四(安全管理器)
欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一 ...
- Delphi word
[转载]在Delphi中使用CreateOleObject方法 (2011-08-24 14:20:47) 转载▼ 标签: 转载 原文地址:在Delphi中使用CreateOleObject方法作 ...
- android布局ui
LinearLayout和RelativeLayout 属性对比 共有属性:java代码中通过btn1关联次控件android:id=”@+id/btn1″ 控件宽度android:layout_wi ...
- HDU 5618 Jam's problem again CDQ分治 BC ROUND 70
题意:给你1e5个点(x,y,z),对于每一个点询问有多少个点(x1,y1,z1)满足x1<=x&&y1<=y&&z1<=z 分析:(官方题解奉上)很 ...
- 富文本HTML编辑器UEditor
Baidu百度开源富文本HTML编辑器UEditor JS代码网 发表于: 2013-10-30 分类:HTML编辑器 点击:2133 UEditor是由百度web前端研发部开发所见即所得富文本H ...
- 建立第一个OpenGL工程(GLUT)
本文参考了<计算机图形学>(Donald Hearn著)的第2.9节. OpenGL基本函数库用来描述图元.属性.几何变换.观察变换和进行许多其他的操作.OpenGL被设计成与硬件无关,因 ...
- NOIP 2014 无线网络发射器选址
水题..直接暴力 #include<cstdio> #include<algorithm> using namespace std; const int inf = 0x3f3 ...