您的位置:首页 > 编程语言 > Java开发

JAVA 反射 总结 之 动态代理

2015-05-20 22:54 399 查看
第一Part 概述

动态代理是指客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象。

动态代理使用场合: 调试  远程方法调用

代理设计模式的原理: 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上;

代理分为静态代理和动态代理。

先介绍一下静态代理:

Demo代码如下:

package com.reflect;

/*
* 静态代理
* 缺点:如果出现了另一个类型的要被代理的对象,该代理类不能使用,
* 需要重新实现一个代理类让这个代理类继承这个接口
* */

interface ClothProduct
{
void product();
}

class NikeClothProduct implements ClothProduct
{
@Override
public void product()
{
System.out.println("Nike Product Cloth");
}
}

class ProxyCloth implements ClothProduct
{
ClothProduct clothProduct;

public ProxyCloth(ClothProduct clothProduct)
{
this.clothProduct = clothProduct;
}

@Override
public void product()
{
clothProduct.product();
}

}

public class TestClothProduct
{

public static void main(String[] args)
{
NikeClothProduct nike = new NikeClothProduct();
ProxyCloth proxy = new ProxyCloth(nike);
proxy.product();
}

}
简单动态代理实现Demo
package com.reflect;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/*
* 动态代理
*
* */

interface Subject
{
void action();
}
//反射是动态代理的关键
class MathodSubject implements Subject
{

@Override
public void action()
{
System.out.println("我是被代理类");
}

}

class MyInvocationHandler implements InvocationHandler
{
Object obj;

// 1:给被代理的对象实例化 2:返回一个代理类的对象
public Object blind(Object obj)
{
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
.getClass().getInterfaces(), this);
}

// 当通过代理类的对象发起对被重写方法的调用时,都会转化为对如下invoke方法的调用
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
Object returnValue = method.invoke(obj, args);// 通过反射调用obj的方法
return returnValue;
}

}

public class TestProxy
{
public static void main(String[] args)
{
//创建被代理类的对象
MathodSubject mathodSubject = new MathodSubject();
//创建实现了InvocationHandler接口的类的对象
MyInvocationHandler proxy = new MyInvocationHandler();
//调用blind方法动态的返回一个实现了mathodSubject所在类 实现接口Subject类的代理类的对象
Subject subject = (Subject) proxy.blind(mathodSubject);
subject.action();//实际是直接调用的是invoke方法

// 可代理其他类
NikeClothProduct nike = new NikeClothProduct();
ClothProduct clothProduct = (ClothProduct) proxy.blind(nike);
clothProduct.product();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: