关于Java动态代理的一点想法

如有错误请指正

1.    动态代理的作用

1. 虚拟机生成的动态代理对象可以轻松地对原有方法进行各种重写

2. 若没有动态代理,想实现重写,必须做一个继承基类的子类

2.  实例演示:

package com.didi.test;

public interface Person {

String skill();

String play();

}

package com.didi.test;

public class Programmer implements  Person{

@Override

public String skill() {

System.out.println("coding-------------------------");

return "调用skill方法";

}

@Override

public String play() {

return null;

}

}

package com.didi.test;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {

Programmer programmer;

public MyInvocationHandler(Programmer programmer) {

this.programmer = programmer;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

System.out.println("before------------");

System.out.println(proxy.getClass().getName());

Object obj =  method.invoke(programmer);

System.out.println("after----------------------");

if(!method.getName().equals("skill")){

return "调用娱乐方法";

}

return obj;

}

}

package com.didi.test;

import java.lang.reflect.Proxy;

public class ProxTest {

public static void main(String[] args) {

Programmer p = new Programmer();

Person programmerProxy = (Person)Proxy.newProxyInstance(

ProxTest.class.getClassLoader(),

p.getClass().getInterfaces(),

new MyInvocationHandler(p));

System.out.println("动态代理类的父类:" + programmerProxy.getClass().getSuperclass().getName());

String mes = programmerProxy.play();

System.out.println(mes);

}

}

控制台打印:

动态代理类的父类:java.lang.reflect.Proxy

before------------

com.sun.proxy.$Proxy0

after----------------------

调用娱乐方法

3. 底层实现原理

1. 如下源码:

public static Object newProxyInstance(ClassLoader loader,

Class<?>[] interfaces,

InvocationHandler h)

throws IllegalArgumentException

{

Objects.requireNonNull(h);

final Class<?>[] intfs = interfaces.clone();

final SecurityManager sm = System.getSecurityManager();

if (sm != null) {

checkProxyAccess(Reflection.getCallerClass(), loader, intfs);

}

/*

* Look up or generate the designated proxy class.

*/

Class<?> cl = getProxyClass0(loader, intfs);

/*

* Invoke its constructor with the designated invocation handler.

*/

try {

if (sm != null) {

checkNewProxyPermission(Reflection.getCallerClass(), cl);

}

final Constructor<?> cons = cl.getConstructor(constructorParams);

final InvocationHandler ih = h;

if (!Modifier.isPublic(cl.getModifiers())) {

AccessController.doPrivileged(new PrivilegedAction<Void>() {

public Void run() {

cons.setAccessible(true);

return null;

}

});

}

return cons.newInstance(new Object[]{h});

} catch (IllegalAccessException|InstantiationException e) {

throw new InternalError(e.toString(), e);

} catch (InvocationTargetException e) {

Throwable t = e.getCause();

if (t instanceof RuntimeException) {

throw (RuntimeException) t;

} else {

throw new InternalError(t.toString(), t);

}

} catch (NoSuchMethodException e) {

throw new InternalError(e.toString(), e);

}

}

2. 源码解析

Proxy.newProxyInstance产生代理类对象,这个方法做了两件重要的事情,首先生成实现传入接口的实现类,然后通过反射创建对象,创建对象时传入一个参数,即我们自己实现的MyInvocationHandler

3. 具体运行情况

当运行代理对象的方法时,虚拟机做如下处理:

1.收集三个参数:代理对象的引用,当前调用方法的方法名,方法的参数

2.调用MyInvocationHandler的invoke方法,参数为上一步收集的参数

4. 实际应用

1. 日志,事务管理

2. 远程过程调用RPC,远程调用时,具体实现在服务端,这时我们在invoke中实现通信即可(调用方法时,让远端的方法被调用,将结果发挥即可),这一切都是通过invoke中的socket通信实现的

 啰嗦一下:

通过动态代理可以轻松地对一个类进行方法增强,改造,自定义

时间: 2024-10-13 01:29:45

关于Java动态代理的一点想法的相关文章

Java 动态代理机制分析及扩展,第 1 部分

引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.通过阅读本文,读者将会对 Java 动态代理机制有更加深入的理解.本文首先从 Java 动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现. 回页首 代理:设计模式 代理是一种常用的设计

java动态代理学习笔记

没事的时候翻看lang.reflect包下的代码,发现有两部分内容:涉及反射和动态代理. 很多地方都可以看到动态代理的影子,只是一直没仔细看下. 在学习之前,先提出几个问题,带着问题来看代码: 1.什么是动态代理? 2.为什么使用动态代理? 3.使用它有哪些好处? 4.哪些地方需要动态代理? --------------------分隔线----------------------------- 和动态代理有关的有两个类 1.interface InvocationHandler Object

理解Java动态代理(1)—找我还钱?我出钱要你的命

代理模式是最常用的一个设计模式之一,理解起来也是很简单,一张图足以说明了,LZ就不废话了. 至于代理模式能干嘛也不是LZ今天想说的,今天主要想简单介绍下JAVA里面的动态代理."动"当然是相对"静"来说的,那么什么是静,怎么就又动了呢?LZ想举个生活中常见的例子来说明,俗话说"谈钱伤感情",但生活所迫LZ曾经可没少找人借个一百两百五的,话说借钱一时爽,还钱--(请自行造句),好点的心平气和的委婉的说,横点的就拳脚相加啊.我们来用接口表示下借钱者这

Java动态代理简单应用

概念 代理模式是基本的设计模式之一,它是开发者为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象.这些操作通常涉及与“实际”对象的通信,因此代理通常充当着中间人的角色. Java动态代理比代理的思想更进一步,因为它可以动态地创建代理并动态地处理对代理方法的调用.在动态代理上所做的所有调用都会被重定向到单一的调用处理器(InvocationHandler)上,调用处理器的工作是揭示调用的类型并确定相应的策略. Java动态代理实现机制采用了反射的思想,有关于反射的基础知识,可以参见博客

java动态代理【一】

java动态代理的定义:为其他目标类的方法增加切面的逻辑,即在执行目标类方法的时候,先去执行一段如校验检测的逻辑代码.java通俗一点就是生成一个继承目标类的子类,并在每个调用方法都添加一段逻辑. 应用场景:当我们从别的项目迁移过来的代码进行修改的时候,如果有一个需求是当要执行某个业务类的所有方法前,需要校验其权限或其他的时候,如果这个类是源代码,我们还可以在类的基础上对每个方法区更改,但若是打包成jar包的类,若该类有接口还可以实现一个代理模式创建一个代理类,没有接口就比较麻烦,但接口一旦多起

Java 动态代理机制分析及扩展

引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.通过阅读本文,读者将会对 Java 动态代理机制有更加深入的理解.本文首先从 Java 动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现. 代理:设计模式 代理是一种常用的设计模式,其

[转]Java 动态代理机制分析及扩展

引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.通过阅读本文,读者将会对 Java 动态代理机制有更加深入的理解.本文首先从 Java 动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现. 代理:设计模式 代理是一种常用的设计模式,其

Java动态代理--&gt;Spring AOP

引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Java基础知识,希望对大家有所帮助.): [1] Java反射知识-->Spring IoC :http://www.iteye.com/topic/1123081 [2] Java动态代理-->Spring AOP :http://www.iteye.com/topic/1123293 [3] 属性

Java动态代理-实战

Java动态代理-实战 只要是写Java的,动态代理就一个必须掌握的知识点,当然刚开始接触的时候,理解的肯定比较浅,渐渐的会深入一些,这篇文章通过实战例子帮助大家深入理解动态代理. 说动态代理之前,要先搞明白什么是代理,代理的字面意思已经很容易理解了,我们这里撇开其他的解释,我们只谈设计模式中的代理模式 什么是代理模式(Proxy) 定义:给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用 在代理模式中,是需要代理对象和目标对象实现同一个接口(如果是不同的接口,那就是适配器模式了),看