先来一个InvocationHandler示例,InvocationHandler类的作用是:对原始对象的方法做一个拦截。

package com.zhang;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; interface HelloSerivce {
void sayHello();
void sayHi();
} interface FuckService {
void fuck();
} class HelloServiceImpl implements HelloSerivce {
@Override
public void sayHello() {
System.out.println("hello zhang");
} @Override
public void sayHi() {
System.out.println("hi zhang");
}
} public class InvocationHandler_Test {
public static void main(String[] args) {
class MyInvocationHandler implements InvocationHandler {
private Object obj;
public MyInvocationHandler(Object obj) {
this.obj = obj;
} //拦截方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if ("sayHello".equals(method.getName())) {
System.out.println("拦截sayHello");
} else if("sayHi".equals(method.getName())) {
System.out.println("拦截sayHi");
}
//调用原始方法
method.invoke(obj, args);
return null;
} @Override
public String toString() {
return "MyInvocationHandler:" + System.currentTimeMillis();
}
} HelloSerivce helloSerivceImpl = new HelloServiceImpl();
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(helloSerivceImpl);
//生成代理
Class<?>[] src = HelloServiceImpl.class.getInterfaces();
Class<?>[] dest = new Class<?>[src.length + 1];
System.arraycopy(src, 0, dest, 0, src.length);
dest[src.length] = FuckService.class; HelloSerivce proxyInstance = (HelloSerivce)Proxy.newProxyInstance(HelloServiceImpl.class.getClassLoader(),
dest, myInvocationHandler);
proxyInstance.sayHello();
proxyInstance.sayHi(); System.out.println(proxyInstance instanceof FuckService);
FuckService fService = (FuckService)proxyInstance;
//报错
fService.fuck();
}
}

dubbo consumer的InvokerInvocationHandler实现了InvocationHandler接口,拦截的是MockClusterInvoker对象的方法,这是jdk动态代理。

public class InvokerInvocationHandler implements InvocationHandler {
private final Invoker<?> invoker;
public InvokerInvocationHandler(Invoker<?> handler){
this.invoker = handler;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
Class<?>[] parameterTypes = method.getParameterTypes();
//如果是Object的方法,直接调用原生对象的方法
if (method.getDeclaringClass() == Object.class) {
return method.invoke(invoker, args);
}
//下面的判断其实是冗余的
if ("toString".equals(methodName) && parameterTypes.length == 0) {
return invoker.toString();
}
if ("hashCode".equals(methodName) && parameterTypes.length == 0) {
return invoker.hashCode();
}
if ("equals".equals(methodName) && parameterTypes.length == 1) {
return invoker.equals(args[0]);
}
//剩下的就需要发送请求给provider了
return invoker.invoke(new RpcInvocation(method, args)).recreate();
}
}

比较一下jdk和javassist动态代理:

//JdkProxyFactory
@SuppressWarnings("unchecked")
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
interfaces, new InvokerInvocationHandler(invoker));
}
//JavassistProxyFactory
@SuppressWarnings("unchecked")
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
}

存在HelloService接口:

public interface HelloService {
String sayHello();
}

Javassist为它动态生成的类代码大致如下:

class com.alibaba.dubbo.common.bytecode.proxy0 implements
com.alibaba.dubbo.rpc.service.EchoService, com.zhang.HelloService {
public <init>(java.lang.reflect.InvocationHandler arg0){
handler=$1;
}
public static java.lang.reflect.Method[] methods;
private java.lang.reflect.InvocationHandler handler; public java.lang.String sayHello(){
Object[] args = new Object[0];
//handler是InvokerInvocationHandler对象
Object ret = handler.invoke(this, methods[0], args);
return (java.lang.String)ret;
}
public java.lang.Object $echo(java.lang.Object arg0){
Object[] args = new Object[1];
args[0] = ($w)$1;
Object ret = handler.invoke(this, methods[1], args);
return (java.lang.Object)ret;
}
}

从上面能看出来:Javassist动态生成的类直接调用InvocationHandler,不是通过代理调用的。

javassist和jdk动态代理的更多相关文章

  1. JDK动态代理与Cglib库

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

  2. AOP的底层实现:JDK动态代理与Cglib动态代理

    转载自 https://www.cnblogs.com/ltfxy/p/9872870.html SpringAOP底层的实现原理: JDK动态代理:只能对实现了接口的类产生代理.(实现接口默认JDK ...

  3. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(3):常用动态代理之JDK动态代理、CGLIB动态代理

    一.动态代理的理解 动态代理的意义在于生成一个占位(又称代理对象),来代理真实对象,从而控制真实对象的访问.        先来谈谈什么是代理模式.        假设这样一个场景:你的公司是一家软件 ...

  4. java学习笔记(中级篇)—JDK动态代理

    一.什么是代理模式 相信大家都知道代理商这个概念,在商业中,代理商无处不在.假设你要去买东西,你不可能去找真正的厂家去买,也不可能直接跟厂家提出需求,代理商就是这中间的一桥梁,连接买家和厂商.你要买或 ...

  5. 动态代理模式——JDK动态代理

    今天,我就来讲一下动态代理的设计模式. 动态代理的意义在于生成一个代理对象,来代理真实对象,从而控制真实对象的访问.操作动态代理需要两个步骤:一.代理对象和真实对象建立代理关系.二.实现代理对象的代理 ...

  6. 浅谈Spring中JDK动态代理与CGLIB动态代理

    前言Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式, ...

  7. JDK 动态代理的实现

    JDK 动态代理的实现 虽然在常用的 Java 框架(Spring.MyBaits 等)中,经常见到 JDK 动态代理的使用,也知道了怎么去写一个 JDK 动态代理的 Demo,但是并不清楚实现原理. ...

  8. JDK动态代理

    一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...

  9. 静态代理和利用反射形成的动态代理(JDK动态代理)

    代理模式 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 静态代理 1.新建 ...

随机推荐

  1. troubleshooting-windows 在 CDH集群环境读取 Hive 表 KrbException: Cannot locate default realm

    KrbException: Cannot locate default realm 解决办法 1)拷贝需要组件的配置文件到项目中的 /resources/目录.如hadoop,目录/etc/hadoo ...

  2. 特征提取的综合实验(多种角度比较SIFT、SURF、BRISK、ORB算法)

    代码:https://files.cnblogs.com/files/jsxyhelu/main.zip 一.基本概念: 特征点提取在“目标识别.图像拼接.运动跟踪.图像检索.自动定位”等研究中起着重 ...

  3. 20145101《Java程序设计》第二周学习总结

    20145101 <Java程序设计>第2周学习总结 教材学习内容总结 在第三章的学习中,我学到了很多新知识点,了解到Java语言中的类型及其变量主要类型为:整数,还有char型,bool ...

  4. 20145208 蔡野《网络对抗》Exp3 Advanced 恶意代码伪装技术实践

    20145208 蔡野<网络对抗>Exp3 Advanced 恶意代码伪装技术实践 木马化正常软件 思路: 在正常软件包中将原本的程序主文件(平时打开程序用的exe文件)改成dll后缀(或 ...

  5. String和int互相转换,String转float

    String-->int int a=Integer.parseIn(str); int-->String String s= a+""; String-->fl ...

  6. 项目管理PV、EV、AC、BAC、EAC、ETC等计算

    PV[Planned Value]计划值:应该完成多少工作?[96版的BCWS] EV[Earned Value]挣值:完成了多少预算工作?[96版的BCWP] AC[Actual Cost]实际成本 ...

  7. MBR记录

    mbr version: 1.6 boot code size: primary data size: extended data size: debug version: no bpb status ...

  8. P4013 数字梯形问题 网络流二十四题

    P4013 数字梯形问题 题目描述 给定一个由 nn 行数字组成的数字梯形如下图所示. 梯形的第一行有 m 个数字.从梯形的顶部的 m 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形 ...

  9. LightOJ 1199 Partitioning Game(sg函数)题解

    题意:可以把一堆石子分成不相等的两堆,不能操作为败 思路:把一个石子拆成两个,变成了两个独立的游戏,mex里加上两者的sg异或.sg打表. 代码: #include<set> #inclu ...

  10. 大数字运算, BigInteger

    package com.ykmimi.test1; import java.math.BigInteger; /** * 大数字运算 * @author ukyor * */ public class ...