java动态代理机制详解

Spring的核心AOP的原理就是java的动态代理机制。

在java的动态代理机制中,有两个重要的类或接口:

1.InvocationHandler(Interface):

  每一个动态代理类都必须要实现InvocatonHandler这个接口,并且每个代理类的实例都关联到一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由

InvocatonHandler这个接口的invoke方法来进行调用。

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

proxy:代表我们所代理的那个真实对象;

method:只带我们所要调用真实对象的某个方法的Method对象;

args:指代的是调用真实对象某个方法时接受的参数。

2.Proxy(Class)

  这个类的作用就是用来动态的创建一个代理对象的类,它提供了许多方法,但是我们用的最多的就是newProxyInstance这个方法:

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interface,InvocationHandler h)throws IllegalArgumentException

loader:一个ClassLoder对象,定义了由那个ClassLoader对象来对生成的代理对象进行加载;

interface:一个Interface对象的数组,表示的是我将要给我的需要代理的对象提供一组什么借口,如果我提供了一组借口给他,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了;

h:一个InvocationHandler对象,表示的是当我这个代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上。

  

【代码清单--1】抽象对象角色:

 package com.huawei.subject;
/**
* 抽象对象角色
* @author Administrator
*
*/
public interface Subject
{
void rent();
void hello();
}

【代码清单--2】真实对象角色

 package com.huawei.subject.Impl;

 import com.huawei.subject.Subject;
/**
* 真实对象角色
* @author Administrator
*
*/
public class RealSubject implements Subject
{ @Override
public void rent()
{
System.out.println("我想要出租my building");
} @Override
public void hello()
{
System.out.println("租客你好");
} }

【代码清单--3】代理类

 package com.huawei.proxy;

 import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; /**
* 动态代理角色
* @author Administrator
*
*/
public class DynamicProxy implements InvocationHandler
{
//这个是我们要代理的真实对象
private Object subject;
//构造方法,给我们要代理的真实对象赋初值
public DynamicProxy(Object obj)
{
this.subject = obj;
} @Override
public Object invoke(Object object, Method method, Object[] args)
throws Throwable
{
//可以在代理真实对象之前进行一些自己的操作
System.out.println("Mrthod :"+method);
//当代理对象调用真实对象的方法时,其会自动的跳转到代理对象的handler对象的invoke方法来进行调用
method.invoke(subject, args); //可以在代理真实对象之后进行一些自己的操作 return null;
} }

【客户端】--测试类

 package com.huawei;

 import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; import com.huawei.proxy.DynamicProxy;
import com.huawei.subject.Subject;
import com.huawei.subject.Impl.RealSubject; public class Main { public static void main(String[] args)
{
//我们要代理的真实对象
Subject realSubject = new RealSubject();
//我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的
InvocationHandler handler = new DynamicProxy(realSubject);
/**
* 通过Proxy的newInstance方法来创建我们的代理对象
* 第一个参数handler.getClass().getClassLoader(),我们这里使用这个
* handler这个类的ClassLoader对象来加载我们的代理对象;
* 第二个参数realSubject.getClass().getInterface(),我们这里为代理对象提供的接口
* 是真实对象所实现的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了;
* 第三个参数handler,这里讲这个代理对象关联到上方的InvocationHandler这个对象上
*/ Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
handler); System.out.println(subject.getClass().getName()); subject.rent();
subject.hello(); } }

【运行结果】

com.sun.proxy.$Proxy0
Mrthod :public abstract void com.huawei.subject.Subject.rent()
我想要出租my building
Mrthod :public abstract void com.huawei.subject.Subject.hello()
租客你好

  通过Proxy.newInstance创建的代理对象是在JVM运行时动态生成的一个对象,它并不是我们的InvocationHandler类型,也不是我们定义的那组接口的类型,而是在运行时动态生成的一个对象,

并且明明方式都是这样的形式,以$开头,proxy为重,最后一个数字表示对象的标号。

subject.rent();
subject.hello();

  这里是通过代理对象来调用实现的那种接口中的方法,这个时候程序就会跳转到由这个代理对象关联到的handler中的invoke方法去执行,而我们

的这个handler对象又接受一个RealSubject类型的参数,表示我要代理的就是这个真实对象,所以此时就会调用handler中invoke方法去执行。

  由结果可知,也证明了当我们通过代理对象来调用方法的时候,实际就是委托有其关联到的handler对象的invoke方法中来调用,并不是自己真实调用,而是通过代理的方法来调用的。

java动态代理模式的更多相关文章

  1. JAVA动态代理模式(从现实生活角度理解代码原理)

    所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...

  2. 关于java动态代理模式

    1. 动态代理 动态代理就是通过代理类是代理类与相关接口不直接发生联系,而在运行期(Runtime)实现动态关联. 动态代理主要用到java.lang.reflect包中的两个类,Invocation ...

  3. Java动态代理模式浅析

    Java代理设计模式 - 静态代理 Java中的动态代理 - 调用处理器 代理设计模式的UML图: 我将首先介绍Java中的各种代理实现方法 Java代理设计模式 - 静态代理 这个例子非常简单,只有 ...

  4. java 动态代理模式(jdk和cglib)

    package proxy.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Met ...

  5. Java 动态代理模式浅析

    目录 Java代理设计模式 - 静态代理 静态代理的优点 静态代理的缺点 Java中的动态代理 - 调用处理器 主要笔记: 动态代理类的限制 代理设计模式的UML图: 我将首先介绍Java中的各种代理 ...

  6. JAVA代理模式与动态代理模式

    1.代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用.代理模式给某 ...

  7. Java设计模式系列之动态代理模式(转载)

    代理设计模式 定义:为其他对象提供一种代理以控制对这个对象的访问. 动态代理使用 java动态代理机制以巧妙的方式实现了代理模式的设计理念. 代理模式示例代码 public interface Sub ...

  8. Java静态代理与动态代理模式的实现

    前言:    在现实生活中,考虑以下的场景:小王打算要去租房,他相中了一个房子,准备去找房东洽谈相关事宜.但是房东他很忙,平时上班没时间,总找不到时间去找他,他也没办法.后来,房东想了一个办法,他找到 ...

  9. java jdk动态代理模式举例浅析

    代理模式概述 代理模式是为了提供额外或不同的操作,而插入的用来替代”实际”对象的对象,这些操作涉及到与”实际”对象的通信,因此代理通常充当中间人角色. java中常用的动态代理模式为jdk动态代理和c ...

随机推荐

  1. 分析Tornado的协程实现

    转自:http://www.binss.me/blog/analyse-the-implement-of-coroutine-in-tornado/ 什么是协程 以下是Wiki的定义: Corouti ...

  2. JAVA设计模式之访问者模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述访问者(Visitor)模式的: 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要 ...

  3. mac 下 chrome 语言环境 设置

    当然,如果把系统语言更改为英文,Chrome.QQ 等一系列软件会自动变成英文界面,而且没有提供切换语言的设置. 啪了下 Google,找到了方法,直接在终端运行后重启 Chrome 即可更改. 英文 ...

  4. NHibernate系列文章十九:NHibernate关系之多对多关系(附程序下载)

    摘要 NHibernate的多对多关系映射由many-to-many定义. 从这里下载本文的代码NHibernate Demo 1.修改数据库 添加Product表 添加ProductOrder表 数 ...

  5. PHP echo 即时输出

    header(“Content-type:text/html;charset=utf-8″); #设置执行时间不限时 set_time_limit(0); #清除并关闭缓冲,输出到浏览器之前使用这个函 ...

  6. 3.openssl speed和openssl rand

    (1).openssl speed 测试加密算法的性能. 支持的算法有: openssl speed [md2] [mdc2] [md5] [hmac] [sha1] [rmd160] [idea-c ...

  7. MySQL_杭州11月销售昨日未上架的SKU_20161212

    #C034杭州11月销售昨日未上架的SKU SELECT 城市,a.订单日期,a.客户数,a.订单数,b.产品数,a.金额,c.销售确认额,c.毛利额,c.毛利率 FROM ( SELECT 城市,订 ...

  8. 获取ServletContext

    ServletConfig       config.getServletContext(): GenericServlet      this.getServletContext(); HttpSe ...

  9. 使用Jquery解析xml的两种方法

    第一种方案(最稳妥): 先将String格式的xml转换为xml对象,然后再用Jquery解析xml对象 var returnDataXml = parseXML(returnData); var p ...

  10. MySQL表分区技术

    MySQL表分区技术 MySQL有4种分区类型: 1.RANGE 分区 - 连续区间的分区 - 基于属于一个给定连续区间的列值,把多行分配给分区: 2.LIST 分区 - 离散区间的分区 - 类似于按 ...