博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java基础之反射生成JDK动态代理
阅读量:4659 次
发布时间:2019-06-09

本文共 3081 字,大约阅读时间需要 10 分钟。

在Java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口。通过这个类和接口可以生成JDK动态代理类或动态代理对象。

JDK动态代理例子:

// 抽象主题角色public interface Sleep {    void sleep();}  // 真实主题角色public class SleepImpl implements Sleep {    @Override    public void sleep() {        System.out.println("熟睡中");    }}  //动态处理器public class DynamicProxyHandler implements InvocationHandler {       private Object obj ;    public  DynamicProxyHandler(final Object obj) {               this.obj = obj;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("睡觉前要刷牙");        Object result = method.invoke(obj, args);        System.out.println("睡醒后要吃早饭");        return null;    }}//测试代码public class ProxyTest {    public static void main(String[] args) {                      Sleep sleep = new SleepImpl();        DynamicProxyHandler dph = new DynamicProxyHandler(sleep);        Sleep sleepProxy = (Sleep) Proxy.newProxyInstance(sleep.getClass().getClassLoader(),                sleep.getClass().getInterfaces(), dph);        sleepProxy.sleep();    }}  结果:睡觉前要刷牙      熟睡中      睡醒后要吃早饭

JDK动态代理源码分析:

生产代理类主要是通过:Proxy.newProxyInstance方法:

@CallerSensitive    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
() { 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); } }

 

转载于:https://www.cnblogs.com/jnba/p/10522670.html

你可能感兴趣的文章
11运算符重载
查看>>
磁盘系统的管理
查看>>
C/S
查看>>
Http Get/Post请求的区别
查看>>
STM32一键下载电路设计原理
查看>>
C语言中函数返回字符串的四种方法
查看>>
10月区块链领域投融资事件盘点
查看>>
Mybatis缓存策略
查看>>
卷积的意义【转】
查看>>
android图形系统详解五:Android绘制模式
查看>>
[剑指offer] 23. 二叉搜索树的后序遍历序列
查看>>
canvas绘画交叉波浪
查看>>
Linux 内核分析
查看>>
试一下:XP ( SP2 ) 本身就支持查杀流氓软件!
查看>>
centos6(7) minimal 基本环境配置
查看>>
P2837晚餐队列安排
查看>>
DP专题
查看>>
UVa 1402 Runtime Error 伸展树
查看>>
笔记本安装SSD固态硬盘详细的优化设置
查看>>
批处理语法介绍
查看>>