参考资料:

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. 八数码难题 双向搜索(codevs 1225)

    题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字 ...

  2. 【译】Nodejs最好的ORM

    TypeORM github: https://github.com/typeorm/typeorm这篇译文是从TypeORM github上的使用说明上翻译过来的,已经提交PR并merge到库中了. ...

  3. JS中的call()和apply()方法区别

    如 果没接触过动态语言,以编译型语言的思维方式去理解javaScript将会有种神奇而怪异的感觉,因为意识上往往不可能的事偏偏就发生了,甚至觉得不可 理喻.如果在学JavaScript这自由而变幻无穷 ...

  4. kafka调试中遇到Connection to node -1 could not be established. Broker may not be available.

    https://blog.csdn.net/Mr_Hou2016/article/details/79484032

  5. 洛谷 P4720 【模板】扩展 / 卢卡斯 模板题

    扩展卢卡斯定理 : https://www.luogu.org/problemnew/show/P4720 卢卡斯定理:https://www.luogu.org/problemnew/show/P3 ...

  6. CodeForces 592D Super M

    先把没用的边去掉,求出包含m个点的最小树.然后求出最小树的直径就可以得到答案了. #include <cstdio> #include <cstring> #include & ...

  7. Jupyter Notebook 基本使用

    Jupyter 官网 IPython Interactive Computing IPython Notebook使用浏览器作为界面,向后台的IPython服务器发送请求,并显示结果.在浏览器的界面中 ...

  8. 转: eclipse 快捷键列表(功能清晰版本)

    转自: http://www.uml.org.cn/mobiledev/201110092.asp Eclipse 在开发中使用到的快捷键很实用噢 Ctrl+1 快速修复(最经典的快捷键,就不用多说了 ...

  9. 用户代码未处理 UpdateException

    无法更新 EntitySet"Project_project",由于它有一个 DefiningQuery.而 <ModificationFunctionMapping> ...

  10. Android5.0(lollipop)新特性介绍(一)

    今年6月的Google I/O大会上.Android L的初次见面我相信让会让非常多android粉丝有些小激动和小期待.当然作为开发人员的我来说,激动不言而喻,毕竟这是自08年以来改变最大的一个版本 ...