Java使用动态代理实现AOP
参考资料:
http://www.importnew.com/15420.html
http://www.cnblogs.com/techyc/p/3455950.html
Spring是借助了动态代理(JDK dynamic proxy)和CGlib两种技术实现AOP的,本文将学习前人的例子使用动态代理模拟AOP的特性。
1. 环境
Java: jdk1.8.0_144
2. 学习动态代理Proxy.newProxyInstance()方法
它的三个参数如下
| 参数名 | 类型 | 说明 |
| loader | ClassLoader | 被代理类的类加载器 |
| interfaces | Class<?>[] | 被代理类实现的interface集合 |
| h | InvocationHandler | 被代理类的所有方法调用,都会绑定到java.lang.reflect.InvocationHandler接口的invoke方法执行 |
3. 实现思路
- 通过JDK dynamic proxy代理目标对象
- 覆盖InvocationHandler的invoke方法,包装被代理对象的方法调用,动态添加逻辑来实现类似于after/before/around的AOP功能
在一定程度上,实现的思路与装饰器模式相似,它们区别在于
- 装饰器模式中的包装类需要知道被包装类的接口细节,而这里不需要
- 装饰器模式不需要使用反射和代理,而这里需要
4. 代码解析
https://github.com/hivsuper/study/tree/master/study-aop
- 将被代理的类及其接口
public interface Calculator {
public int add(int a, int b);
}
public class CalculatorImpl implements Calculator {
@Override
public int add(int a, int b) {
return a + b;
}
}
- 绑定被代理对象的调度接口
import java.lang.reflect.InvocationHandler;
public abstract class AbstractHandler implements InvocationHandler {
private Object targetObject;
public Object getTargetObject() {
return targetObject;
}
public void setTargetObject(Object targetObject) {
this.targetObject = targetObject;
}
}
- 生成代理的简单工厂
import java.lang.reflect.Proxy;
import java.util.List; public class ProxyFactory {
public static Object getProxy(Object targetObject, List<AbstractHandler> handlers) {
Object proxyObject = null;
if (handlers.size() > 0) {
proxyObject = targetObject;
for (AbstractHandler abstractHandler : handlers) {
abstractHandler.setTargetObject(proxyObject);
proxyObject = Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), abstractHandler);
}
return proxyObject;
} else {
return targetObject;
}
}
}
- 测试类
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List; import org.junit.Assert;
import org.junit.Test;
import org.lxp.study.aop.AbstractHandler;
import org.lxp.study.aop.ProxyFactory; public class CalculatorImplTest { @Test
public void testAdd() throws Exception {
Calculator calculator = new CalculatorImpl();
AbstractHandler before = new AbstractHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("...before...");
return method.invoke(getTargetObject(), args);
}
};
AbstractHandler after = new AbstractHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(getTargetObject(), args);
System.out.println("...after...");
return result;
}
};
AbstractHandler around = new AbstractHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
StringBuilder sb = new StringBuilder();
for (Object arg : args) {
sb.append(arg).append(",");
}
System.out.println("Parameters:" + sb.substring(0, sb.length() - 1));
Object result = method.invoke(getTargetObject(), args);
System.out.println("Result:" + result);
return result;
}
};
List<AbstractHandler> handlers = new ArrayList<AbstractHandler>();
handlers.add(before);
handlers.add(after);
handlers.add(around);
Calculator proxy = (Calculator) ProxyFactory.getProxy(calculator, handlers);
Assert.assertEquals(30, proxy.add(20, 10));
} }
Java使用动态代理实现AOP的更多相关文章
- Java JDK 动态代理(AOP)使用及实现原理分析
一.什么是代理? 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 代理模式U ...
- Java动态代理-->Spring AOP
引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Jav ...
- Java 动态代理与AOP
动态代理与AOP 代理模式 代理模式给某一个目标对象(target)提供代理对象(proxy),并由代理对象控制对target对象的引用. 模式图: 代理模式中的角色有: 抽象对象角色(Abstrac ...
- Java 动态代理及AOP实现机制
AOP实现机制http://www.iteye.com/topic/1116696 AOP: (Aspect Oriented Programming) 面向切面编程AOP包括切面(aspect).通 ...
- Java动态代理(AOP)
目录 一.代理 1. 什么是代理? 2. 使用代理模式的作用 3. 实现代理的方式 二.静态代理 1. 模拟用户购买u盘 2. 静态代理的缺点 三.动态代理 四. JDK 动态代理 1. Invoca ...
- [JAVA]动态代理与AOP的千丝万缕
动态代理与AOP的联系 别的不说,直接上图 首先是AOP切面编程 什么是切面?(自己心里想想就ok)所以所谓的切面编程,你也就懂得大体了,只是这个被切的是个程序而已 那么AOP与动态代理有什么关系呢? ...
- java的动态代理机制详解
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- java中动态代理实现机制
前言: 代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系 ...
- 动态代理到基于动态代理的AOP
动态代理,是java支持的一种程序设计方法. 动态代理实现中有两个重要的接口和类,分别是InvocationHandler(interface),Proxy(class). 要实现动态代理,必须要定义 ...
随机推荐
- cobbler ks文件解释--转载
cobbler中ks.cfg文件配置详解 许多系统管理员宁愿使用自动化的安装方法来安装红帽企业 Linux.为了满足这种需要,红帽创建了kickstart安装方法.使用kickstart ...
- JVM(零):走入JVM
JVM(零):走入JVM 本系列主要讲述JVM相关知识,作为本系列的第一篇文章,本文从Java为什么是一个跨平台的语音开始介绍,逐步引入Java虚拟机的概念,并给出一个JVM相关知识图谱,可以让读者从 ...
- Jinja2如何默认将None 值显示为空字符串?
在Jinja模板中 {% if User %} {{ User.name }} {% endif %} 可以简化为下面的写法,同时,保证返回值为空,而不是显示为“None” {{ User.name ...
- Mysql不同存储引擎的表转换方法
Mysql不同存储引擎的表转换方法 1.Alter table直接修改表的存储引擎,但是这样会导致大量的系统开销,Mysql为此要执行一个就表向新表的逐行复制.在此期间,转换操作可能会占用服务器的所有 ...
- Desert King (poj 2728 最优比率生成树 0-1分数规划)
Language: Default Desert King Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 22113 A ...
- 利用Druid实现应用和SQL监控
一.关于Druid Druid是一个JDBC组件,它包括三部分: DruidDriver 代理Driver,能够提供基于Filter-Chain模式的插件体系. DruidDataSource 高效可 ...
- webpack-Targets(构建目标)
构建目标(Targets) 因为服务器和浏览器代码都可以用 JavaScript 编写,所以 webpack 提供了多种构建目标(target),你可以在你的 webpack 配置中设置. webpa ...
- AES算法加密java实现
package cn.itcast.coderUtils; import java.security.Key; import javax.crypto.Cipher; import javax.cry ...
- java notify notifyAll
notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法. void notify(): 唤醒一个正在等待该对象的线程.void notifyAll(): 唤醒所 ...
- soapUI系列之—-04 问题解决 获取接口返回报文response报错
1. SoapUI+Groovy中"org.apache.xmlbeans.XmlException: error: Unexpected element: CDATA" 通过So ...