参考资料:

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的更多相关文章

  1. Java JDK 动态代理(AOP)使用及实现原理分析

    一.什么是代理? 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 代理模式U ...

  2. Java动态代理-->Spring AOP

    引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Jav ...

  3. Java 动态代理与AOP

    动态代理与AOP 代理模式 代理模式给某一个目标对象(target)提供代理对象(proxy),并由代理对象控制对target对象的引用. 模式图: 代理模式中的角色有: 抽象对象角色(Abstrac ...

  4. Java 动态代理及AOP实现机制

    AOP实现机制http://www.iteye.com/topic/1116696 AOP: (Aspect Oriented Programming) 面向切面编程AOP包括切面(aspect).通 ...

  5. Java动态代理(AOP)

    目录 一.代理 1. 什么是代理? 2. 使用代理模式的作用 3. 实现代理的方式 二.静态代理 1. 模拟用户购买u盘 2. 静态代理的缺点 三.动态代理 四. JDK 动态代理 1. Invoca ...

  6. [JAVA]动态代理与AOP的千丝万缕

    动态代理与AOP的联系 别的不说,直接上图 首先是AOP切面编程 什么是切面?(自己心里想想就ok)所以所谓的切面编程,你也就懂得大体了,只是这个被切的是个程序而已 那么AOP与动态代理有什么关系呢? ...

  7. java的动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  8. java中动态代理实现机制

    前言: 代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系 ...

  9. 动态代理到基于动态代理的AOP

    动态代理,是java支持的一种程序设计方法. 动态代理实现中有两个重要的接口和类,分别是InvocationHandler(interface),Proxy(class). 要实现动态代理,必须要定义 ...

随机推荐

  1. spring security3.1升级到4.1问题(1)访问/j_spring_security_check 404

    升级完后,发现登录不进去,把post改成get好了,但是系统的提交表单功能都不能用了,也是解决了很长时间,最后找到了根本原因. spring sercurity 4.0 csrf保护是默认开启的,cs ...

  2. 数字游戏(codevs 1085)

    题目描述 Description 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共 ...

  3. PHP 基础复习 2018-06-17

    (1)AJAX Asynchronous JavaScript And XML(异步 JavaScript 及 XML) (2)创建 XMLHttpRequest 对象 不同的浏览器使用不同的方法来创 ...

  4. Windows下SVN服务器及客户端的使用

    原文地址:windows下配置VisualSVN Server服务器 作者:Deem_passion 下载安装文件: 服务端安装文件:VisualSVN-Server-1.6.2 客户端安装文件:To ...

  5. pip命令自动补全功能;设置代理;使用国内源

    这是pip自带的功能 执行的脚本 把脚本写入.zshrc或者profile等里面,执行source立即生效 设置代理: pip --proxy=http://username:password@pro ...

  6. 【网络】TCP的拥塞控制

    一.拥塞控制的一般原理 拥塞:对网络中某一资源的需求超过了该资源所能提供的可用部分 拥塞控制是防止过多的数据注入到网络,这样可以使网络中的路由器或链路不致过载,拥塞控制是一个全局性的过程. 流量控制往 ...

  7. Android使用am命令实现拨打电话、打开应用

    前提: 在Android 通话自己主动化測试中会用到am命令去拨打电话.打开音乐播放器播放音乐等等操作. 这里总结一下am命令. Android am命令: (1)命令參数: am start -n ...

  8. Visual Studio 2017中使用正则修改部分内容 如何使用ILAsm与ILDasm修改.Net exe(dll)文件 C#学习-图解教程(1):格式化数字字符串 小程序开发之图片转Base64(C#、.Net) jquery遍历table为每一个单元格取值及赋值 。net加密解密相关方法 .net关于坐标之间一些简单操作

    Visual Studio 2017中使用正则修改部分内容   最近在项目中想实现一个小工具,需要根据类的属性<summary>的内容加上相应的[Description]特性,需要实现的效 ...

  9. 性能监控 -- 中间件性能监控【Weblogic控制台】

    通过WebLogic管理控制台可以实时获取各性能指标,通过控制台,可以对weblogic的性能及运行状况,发布的应用.资源等进行监视 1. 进入Weblogic管理控制台,单击服务器,选择一台需监控的 ...

  10. 蓝牙4.0BLE cc2540 usb-dongle的 SmartRF Packet Sniffer 抓取数据方法 【原创,多图】

    蓝牙4.0BLE cc2540 usb-dongle的 SmartRF Packet Sniffer 抓取数据方法 [原创,多图] spm=a1z10.1.w4004-5319414070.11.Zd ...