(转)使用JDK中的Proxy技术实现AOP功能
http://blog.csdn.net/yerenyuan_pku/article/details/52863780
AOP技术在企业开发中或多或少都会用到,但用的最多的大概就是做权限系统时,在做权限系统时,我们可能需要粗粒度的权限控制和细粒度的权限控制,对于细粒度的权限控制,我们主要是对方法进行拦截,对方法进行拦截之后,判断用户是否是有权限,有权限就执行该方法,没有权限就不能执行该方法。
现在我们借助一个例子来说明怎么使用JDK中的Proxy技术来实现AOP功能,并且不借助任何其他的框架。
首先新建一个普通的Java Project,名称为AOP。接着在src目录下新建一个it.cast.service包,并在该包下创建PersonService接口,其代码为:
public interface PersonService {
public void save(String name);
public void update(String name, Integer personid);
public String getPersonName(Integer personid);
}
- 1
紧接着在src目录下新建一个it.cast.service.impl包,并在该包下创建PersonService接口的实现类——PersonServiceBean.java,其代码为:
public class PersonServiceBean implements PersonService {
private String user = null;
public String getUser() {
return user;
}
public PersonServiceBean() {}
public PersonServiceBean(String user) {
this.user = user;
}
public void save(String name) {
System.out.println("我是save()方法");
}
public void update(String name, Integer personid) {
System.out.println("我是update()方法");
}
public String getPersonName(Integer personid) {
System.out.println("我是getPersonName()方法");
return "xxx";
}
}
- 1
现在提出这样一个需求:
- 拦截所有业务方法。
- 判断用户是否有权限,有权限就允许他执行业务方法,没有权限就不允许他执行业务方法。(是否有权限是根据user是否为null作为判断依据的)
为实现这样的业务需求,可能有人这样写:
public class PersonServiceBean implements PersonService {
private String user = null;
public String getUser() {
return user;
}
public PersonServiceBean() {}
public PersonServiceBean(String user) {
this.user = user;
}
public void save(String name) {
if (user != null) {
System.out.println("我是save()方法");
}
}
public void update(String name, Integer personid) {
if (user != null) {
System.out.println("我是update()方法");
}
}
public String getPersonName(Integer personid) {
if (user != null) {
System.out.println("我是getPersonName()方法");
}
return "xxx";
}
}
- 1
很显然这样做非常不妥,于是我们就要另寻他路,这个时候很容易想到动态代理技术,对于动态代理技术如有不甚清楚的,可以翻阅我的笔记动态代理(一)——动态代理入门。现在我们就使用JDK中的Proxy技术来生成PersonServiceBean对象的代理对象,但要记住在Java里面有这样一个约定:要想创建某一个对象的代理对象,那么该对象必须实现一个接口。
在src目录下新建一个it.cast.aop包,并在该包下新建一个类——JDKProxyFactory.java,专门用于创建代理对象,其代码为:
public class JDKProxyFactory implements InvocationHandler {
private Object targetObject; // 代理的目标对象
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
/*
* 第一个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器
* 第二个参数设置代理类实现的接口
* 第三个参数设置回调对象,当代理对象的方法被调用时,会委派给该参数指定对象的invoke方法
*/
return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
PersonServiceBean bean = (PersonServiceBean)this.targetObject;
Object result = null;
if (bean.getUser() != null) { // 有权限
result = method.invoke(targetObject, args); // 把方法调用委派给目标对象
}
return result;
}
}
- 1
结论:当目标类实现了一个接口,我们就可以使用JDK的Proxy来生成代理对象。
最后在src目录下新建一个juint.test包,在该包下新建一个单元测试类——AOPTest.java。我们先将该类的代码写为:
public class AOPTest {
@Test
public void proxyTest() {
JDKProxyFactory factory = new JDKProxyFactory();
PersonService service = (PersonService) factory.createProxyInstance(new PersonServiceBean("xxx"));
service.save("888");
}
}
- 1
测试proxyTest()方法,Eclipse控制台会打印:
若将AOPTest类的代码改为:
public class AOPTest {
@Test
public void proxyTest() {
JDKProxyFactory factory = new JDKProxyFactory();
PersonService service = (PersonService) factory.createProxyInstance(new PersonServiceBean());
service.save("888");
}
}
- 1
再次测试proxyTest()方法,会发现Eclipse控制台什么也不会打印。
(转)使用JDK中的Proxy技术实现AOP功能的更多相关文章
- JDK中的Proxy技术实现AOP功能
1.需求,用户在执行某个业务方法时我们需要对这个用户进行判断是否具有权限(或者说用户是否登录了)? 例如修改用户信息,我们在update()方法前判断当前用户user是否为null(表示没有权限或者没 ...
- SpringBoot中使用LoadTimeWeaving技术实现AOP功能
目录 1. 关于LoadTimeWeaving 1.1 LTW与不同的切面织入时机 1.2 JDK实现LTW的原理 1.3 如何在Spring中实现LTW 2. Springboot中使用LTW实现A ...
- JAVA中的代理技术(静态代理和动态代理)
最近看书,有两个地方提到了动态代理,一是在Head First中的代理模式,二是Spring AOP中的AOP.所以有必要补充一下动态代理的相关知识. Spring采用JDK动态代理和CGLib动态代 ...
- 初探Java设计模式4:JDK中的设计模式
JDK中设计模式 本文主要是归纳了JDK中所包含的设计模式,包括作用和其设计类图.首先来个总结,具体的某个模式可以一个一个慢慢写,希望能对研究JDK和设计模式有所帮助.一.设计模式是什么(1)反复出现 ...
- JDK中的设计模式
Creational(创建模式) Abstract factory: 创建一组有关联的对象实例.这个模式在JDK中也是相当的常见,还有很多的framework例如Spring.我们很容易找到这样的实例 ...
- (转载)JDK中的设计模式
写的很好,学习道路更轻松一些 原文地址:http://blog.csdn.net/gtuu0123/article/details/6114197 JDK中设计模式 分类: Java相关 设计模式 2 ...
- Binder Proxy技术方案
Binder Proxy技术方案 作者 低端码农 时间 2014.08.23 0x0 看到有多朋友尝试通过hook系统进程system_process的ioctl,以企图截获系统的IPC通讯.这个方法 ...
- JDK中所包含的设计模式
本文主要是归纳了JDK中所包含的设计模式,包括作用和其设计类图.首先来个总结,具体的某个模式可以一个一个慢慢写,希望能对研究JDK和设计模式有所帮助. 一.设计模式是什么(1)反复出现问题的解决方案( ...
- 第89节:Java中的反射技术
第89节:Java中的反射技术 反射技术是动态的获取指定的类,和动态的调用类中的内容(没有类前就可以创建对象,将对象的动作完成,这就是动态的获取指定的类). 配置文件把具体实现的类名称定义到配置文件中 ...
随机推荐
- Barn Repair
链接 分析:我们不断统计相邻两个元素之间的差值,按照差值从大到小排序,在进行贪心即可 /* PROB:barn1 ID:wanghan LANG:C++ */ #include "iostr ...
- JAVA Synchronized (一)
<编程思想之多线程与多进程(1)——以操作系统的角度述说线程与进程>一文详细讲述了线程.进程的关系及在操作系统中的表现,这是多线程学习必须了解的基础.本文将接着讲一下Java线程同步中的一 ...
- 转载:PowerPivot for excel 100 Create KPI
PowerPivot for excel 100 Create KPI 最近在了解PowerPivot,遇到了一些问题,不过还好最近都解决了,下面介绍一下关于在PowerPivot里面如何创 ...
- HDU 1207 汉诺塔II (简单DP)
题意:中文题. 析:在没有第四个柱子时,把 n 个盘子搬到第 3 个柱子时,那么2 ^ n -1次,由于多了一根,不知道搬到第四个柱子多少根时是最优的, 所以 dp[i] 表示搬到第4个柱子 i 个盘 ...
- 斯坦福CS231n—深度学习与计算机视觉----学习笔记 课时6
课时6 线性分类器损失函数与最优化(上) 多类SVM损失:这是一个两分类支持向量机的泛化 SVM损失计算了所有不正确的例子,将所有不正确的类别的评分,与正确类别的评分之差加1,将得到的数值与0作比较, ...
- 洛谷 - P1443 - 马的遍历 - bfs
略有收获的bfs,使用了try_enqueue函数使得加入队列非常方便.性能理论上是一样的因为是inline? 还有就是左对齐是使用%-4d,相对于右对齐的%4d,还有右对齐前导零的%04d,自己试一 ...
- bzoj 3992: [SDOI2015]序列统计【原根+生成函数+NTT+快速幂】
还是没有理解透原根--题目提示其实挺明显的,M是质数,然后1<=x<=M-1 这种计数就容易想到生成函数,但是生成函数是加法,而这里是乘法,所以要想办法变成加法 首先因为0和任何数乘都是0 ...
- 【Tip】JavaScript
『JavaScript』 『引用网络资源』 JQuery <script src="http://code.jquery.com/jquery-latest.js">& ...
- Apache-kylin-2.0.0-bin-hbase1x.tar.gz的下载与安装(图文详解)
首先,对于Apache Kylin的安装,我有话要说. 由于Apache Kylin本身只是一个Server,所以安装部署还是比较简单的.但是它的前提要求是Hadoop.Hive.HBase必须已经安 ...
- 题解报告:poj 1113 Wall(凸包)
Description Once upon a time there was a greedy King who ordered his chief Architect to build a wall ...