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. win7安装xampp,提示windows找不到-n文件(安装成功后,443端口占用,apache服务器无法正常启动)

    1. 环境:win7 64位安装xampp 32位. xampp下载地址:https://www.apachefriends.org/download.html 2. 安装过程最后,报错,提示wind ...

  2. 货币单位类RmbUnit

    import java.math.BigDecimal; public enum RmbUnit { FEN{ public String toFen(String amt) { BigDecimal ...

  3. dataguard 归档丢失(主库中无此丢失归档处理),备库基于SCN恢复

    dataguard 归档丢失(主库中无此丢失归档处理),备库基于SCN恢复 环境: OS: CentOS 6.5 DB: Oracle 10.2.0.5 1.主备库环境 主库: SQL> sel ...

  4. Linux操作系统学习笔记

    关于Linux详细介绍可以参见:http://blog.csdn.net/hguisu/article/details/6122513 关于Linux的常用命令可以参见:http://blog.csd ...

  5. submit异步提交 回调的方法

    背景: mvc模式下,当submit表单的时候,后台Control自动绑定Model类,但是如果不用submit来提交,改用ajax提交的时候,后台Control无法获取前台form表单内相应Name ...

  6. 【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

    简单介绍:Enumerable 和 Queryable 他们都是静态类,位于命名控件 System.Linq下,分别为IEnumerable<T>和IQueryable<T>提 ...

  7. C# JSON to object

    /// <summary> /// json格式转换(引用System.Web.Extension类库) /// </summary> /// <param name=& ...

  8. xcode5-ios7-如何添加120x120、152x152、76x76图标

    以120x120为例: 添加Icon_120x120.png-->.plist添加Icon files-->App Icons自动变化 1. 2. 3. ================= ...

  9. Brn系列商城3.0测试版正式发布,欢迎大家下载测试

    BrnShop商城3.0测试版和BrnMall商城3.0测试版正式发布,欢迎大家下载测试(点击下载).测试结束后将会发布正式版和MySQL版本. 测试过程中发现bug欢迎大家给我们反馈,反馈邮箱:br ...

  10. WebForm 简单控件、复合控件

    简单控件: Label:被编译成span 样式表里设置lable的高度:  display:inline-block; Text  --文本 ForeColor  --字体颜色 Visible  -- ...