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. Hihocoder 1035 [树形dp]

    /* 题意: 不要低头,不要放弃,不要气馁,不要慌张. PS:人生第一道自己独立做出来的树形dp... 给一棵树,标号1到n,每条边有两个权值,步行时间和驾车时间.车在1号点. 给m个必须访问的关键点 ...

  2. 关于sublime text2

    转自:http://www.qianduan.net/essential-to-sublime-the-text-2-plugins.html Sublime Text 2是一个轻量.简洁.高效.跨平 ...

  3. C++引用与指针

    在做函数参数时, 引用不可以设置默认值, 指针可以 void fun(const string& url,  string* domain = NULL); 另const放在函数后面, 表示这 ...

  4. 【MySQL】InnoDB: Error: checksum mismatch in data file 报错

    参考:http://www.jb51.net/article/66951.htm 用5.7版本启动原5.5实例后,再用5.5启动出现以下报错 InnoDB: Error: checksum misma ...

  5. vs2010 编译boost库

    下载boost_1_49_0 打开vs2010工具dos, 再进入E:\boost_1_49_0 运行: bootstrap.bat 然后再运行: bjam stage --toolset=msvc- ...

  6. NHibernate系列文章八:NHibernate对象一级缓存

    摘要 Nhibernatea缓存非常强大,按照缓存存储在Session对象还是SessionFactory对象分为一级缓存和二级缓存. 一级缓存存在于Session对象里,也叫Session缓存,由S ...

  7. hive 中窗口函数row_number,rank,dense_ran,ntile分析函数的用法

    hive中一般取top n时,row_number(),rank,dense_ran()这三个函数就派上用场了, 先简单说下这三函数都是排名的,不过呢还有点细微的区别. 通过代码运行结果一看就明白了. ...

  8. Asp.Net 获取FileUpload控件的文件路径、文件名、扩展名

    string fileNameNo = Path.GetFileName(FileUploadImg.PostedFile.FileName); //获取文件名和扩展名string Directory ...

  9. vsnprintf

    http://www.cplusplus.com/reference/cstdio/vsnprintf/ int vsnprintf (char * s, size_t n, const char * ...

  10. CSS BOX模型

    对于box模型概念的理解以及它与决定元素最终尺寸的方式有何关系,是理解如何设定网 页上的元素位置的基础.box模型应用到块级元素.一个随之而来的概念,内联布局模型 定义了如何设定内联元素的位置. 对于 ...