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容器来完成,这种从具体对象手中交出控制的做法是非常有价 ...
随机推荐
- R语言中的箱图介绍 boxplot
画箱图的函数: boxplot()##help(boxplot)查询具体用法 图例的解释: 如下图,是两个简单的箱图. 中间的箱子的上下边,分别是第三,一个四分位数. 中间的黑线是第二四分位数(中 ...
- 不能设置sublime text 2 为默认编辑器
今天遇到一个有趣的事情,当我设置 css 样式表的默认打开方式的时候,却始终无法设置成功,系统总是随机选取一种打开方式来打开文件.比如:pdf.DW.txt等方式. 我设置默认打开方式的步骤如下: 1 ...
- POJ1182
这题需要注意就是 并查集中 相对位置 注意与绝对距离区别 #include<cstdio> #define maxn 50005 int ans,i,a,b,p,fa,fb,n,k; in ...
- Zend Framework XML外部实体和安全绕过漏洞
漏洞版本: Zend Framework 1.x 漏洞描述: Bugtraq ID:66358 Zend Framework是一款开放源代码的PHP5开发框架实现. Zend Framework存在多 ...
- Codeforces Round #306 (Div. 2)
A. Two Substrings You are given string s. Your task is to determine if the given string s contains t ...
- SQL、LINQ、Lambda 三种用法
SQL LinqToSql Lambda 1. 查询Student表中的所有记录的Sname.Ssex和Class列.select sname,ssex,class from studentL ...
- 关于 tomcat 集群中 session 共享的三种方法
前两种均需要使用 memcached 或redis 存储 session ,最后一种使用 terracotta 服务器共享. 建议使用 redis,不仅仅因为它可以将缓存的内容持久化,还因为它支持的单 ...
- LRU与MRU算法
1.Cache Hit and Cache Miss 当使用者第一次向数据库发出查询数据的请求的时候,数据库会先在缓冲区中查找该数据,如果要访问的数据恰好已经在缓冲区中(我们称之为Cache Hit) ...
- 应用MVP模式写出可维护的优美Android应用
在Android开发中,我们常常会动辄写出数千行的Java类,而当一个Activity有4.5千行的时候,想找一个逻辑在哪儿就会显得异常痛苦了.比如想在数据加载错误的时候,显示一个提示信息,上上下下得 ...
- 提示29. 怎样避免延迟加载或Load()阅读器问题
提示29. 怎样避免延迟加载或Load()阅读器问题 如果你有如下这样的代码: 1 var results = from c in ctx.Customers 2 where c.SalesPerso ...