您的位置:首页 > 职场人生

黑马程序员:Java基础总结----静态代理模式&动态代理

2013-07-14 16:10 741 查看
黑马程序员:Java基础总结

静态代理模式&动态代理

ASP.Net+Android+IO开发.Net培训、期待与您交流!

静态代理模式

public class Ts
{
public static void main(String[]
args) throws Exception {
[align=left] // 通过中介公司生产一批衣服[/align]
[align=left] ClothingProduct cp = new ProxCompany(new LiNingCompany());[/align]
[align=left] cp.productClothing();[/align]
[align=left] }[/align]

[align=left]}[/align]

[align=left]/**[/align]
[align=left] * 定义生产一批衣服功能的接口[/align]
[align=left] *[/align]
[align=left] */[/align]
[align=left]interface ClothingProduct {[/align]

void productClothing(); //
有生产一批衣服的功能

[align=left]}[/align]

[align=left]/**[/align]
[align=left] *[/align]
[align=left] * 代理类:中介公司[/align]
[align=left] *[/align]
[align=left] */[/align]
class ProxCompany implements ClothingProduct
{

private ClothingProduct cp ; //
中介公司不会生产衣服,需要找一家真正能生产衣服的公司

[align=left] ProxCompany(ClothingProduct cp) {[/align]
[align=left] super();[/align]
this.cp =
cp;
[align=left] }[/align]

[align=left] @Override[/align]
public void productClothing()
{

[align=left] System. out.println("收取1000块钱的中介费" );[/align]
[align=left] cp.productClothing();[/align]

[align=left] }[/align]

[align=left]}[/align]

[align=left]/**[/align]
[align=left] *[/align]
[align=left] * 李宁公司是生产服装的目标类[/align]
[align=left] *[/align]
[align=left] */[/align]
class LiNingCompany implements ClothingProduct
{

[align=left] @Override[/align]
public void productClothing()
{

[align=left] System. out.println("生产一批衣服。。。。" );[/align]
[align=left] }[/align]

[align=left]}[/align]

上面程序的做法,使用的模式是静态代理模式

静态代理模式在现实编程中的弊端:
它的特征是代理类和目标对象的类都是在编译期间确定下来的,不利于程序上的扩展,上面示例中,如果客户还想找一个“生产一批鞋子”的工厂,那么还需要新增加一个代理类和一个目标类。如果客户还需要很多其他的服务,就必须一一的添加代理类和目标类。那就需要写很多的代理类和目标类

动态代理技术

java.lang.reflect

类 Proxy


Proxy
提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。


构造方法摘要
protected
Proxy(InvocationHandler h)


使用其调用处理程序的指定值从子类(通常为动态代理类)构建新的
Proxy
实例。
字段摘要
protected  InvocationHandler
h


此代理实例的调用处理程序。
方法摘要
static InvocationHandler
getInvocationHandler(Object proxy)


返回指定代理实例的调用处理程序。
static Class<?>
getProxyClass(ClassLoader loader, Class<?>... interfaces)


返回代理类的
java.lang.Class
对象,并向其提供类加载器和接口数组。
static boolean
isProxyClass(Class<?> cl)


当且仅当指定的类通过
getProxyClass
方法或
newProxyInstance
方法动态生成为代理类时,返回 true。
staticObject
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)


返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的
invoke
方法。


public interface InvocationHandler 方法摘要


Object
invoke(Object proxy, Method method,Object[] args)


在代理实例上处理方法调用并返回结果。

参数:
proxy
- 在其上调用方法的代理实例
method
- 对应于在代理实例上调用的接口方法的
Method
实例。
Method
对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。
args
- 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为
null
。基本类型的参数被包装在适当基本包装器类(如
java.lang.Integer
java.lang.Boolean
)的实例中。返回:从代理实例的方法调用返回的值。如果接口方法的声明返回类型是基本类型,则此方法返回的值一定是相应基本包装对象类的实例;否则,它一定是可分配到声明返回类型的类型。如果此方法返回的值为
null
并且接口方法的返回类型是基本类型,则代理实例上的方法调用将抛出
NullPointerException
。否则,如果此方法返回的值与上述接口方法的声明返回类型不兼容,则代理实例上的方法调用将抛出
ClassCastException


[align=left]import java.lang.reflect.InvocationHandler;[/align]
[align=left]import java.lang.reflect.Method;[/align]
[align=left]import java.lang.reflect.Proxy;[/align]
[align=left]import java.util.ArrayList;[/align]
[align=left]import java.util.Collection;[/align]

public class Ts
{
public static void main(String[]
args) throws Exception {
[align=left] ArrayList test = new ArrayList();[/align]
//
代理只可以强转换成接口
[align=left] Collection list = (Collection ) getProxy(test, new MyAdvice());[/align]
[align=left] list.add(123);[/align]
[align=left] list.add(123);[/align]
[align=left] System. out.println(list);[/align]

[align=left] }[/align]

public staticObject
getProxy(finalObject target, final Advice
adv)/* 终态是因为内部类调用 */ {
//
返回一个指定接口的代理类实例 obj
[align=left] Object obj = Proxy. newProxyInstance([/align]
//
定义代理类的类加载器
[align=left] target.getClass().getClassLoader(),[/align]
//
代理类要实现的接口列表
[align=left] target.getClass().getInterfaces(),[/align]
//
指派方法调用的调用处理程序 InvocationHandler
new InvocationHandler()
{

[align=left] @Override[/align]
publicObject
invoke(Object proxy, Method method,
Object[] args) throws Throwable
{
[align=left] adv.begintime(method);[/align]
//target目标
args方法参数,调用原来的方法
[align=left] Object retVal = method.invoke(target, args);[/align]
[align=left] adv.endtime(method);[/align]
[align=left] return retVal;[/align]
[align=left] }[/align]
[align=left] });[/align]

[align=left] return obj;[/align]
[align=left] }[/align]
[align=left]}[/align]
[align=left]//插入的建议接口[/align]
interface Advice
{
void begintime(Method
method);

void endtime(Method
method);
[align=left]}[/align]
[align=left]//我的建议[/align]
class MyAdvice implements Advice
{

[align=left] @Override[/align]
public void begintime(Method
method) {
[align=left] Long time = System. currentTimeMillis();[/align]
System. out.println(method.getName()
+ time);
[align=left] }[/align]

[align=left] @Override[/align]
public void endtime(Method
method) {
[align=left] Long time = System. currentTimeMillis();[/align]
System. out.println(method.getName()
+ time);
[align=left] }[/align]

[align=left]}[/align]

一个更巧妙的方法:自定义一个处理程序
public class Ts
{
public static void main(String[]
args) throws Exception {
[align=left] ProxyHandler handler= new ProxyHandler();[/align]
[align=left] ClothingProduct cp2=(ClothingProduct)handler.newProxyInstance( new LiNingCompany());[/align]
[align=left] cp2.productClothing();[/align]

[align=left] }[/align]

[align=left]}[/align]

class ProxyHandler implements InvocationHandler
{

/*
目标对象 */
[align=left] privateObject target ;[/align]

/*
创建目标对象的代理对象 */
publicObject
newProxyInstance(Object target) {

this.target =
target;

[align=left] /*[/align]
[align=left] * 第一个参数:定义代理类的类加载器[/align]
[align=left] * 第二个参数:代理类要实现的接口 列表[/align]
[align=left] * 第三个参数:指派方法调用的调用处理程序[/align]
[align=left] */[/align]
[align=left] return Proxy.newProxyInstance(this. target.getClass().getClassLoader(),[/align]
[align=left] this.target .getClass().getClasses(), this);[/align]

[align=left] }[/align]

[align=left] @Override[/align]
publicObject
invoke(Object proxy, Method method,Object[] args)
throws Throwable
{

[align=left] Object result = null;[/align]

[align=left] System. out.println("目标对象上的方法调用之前可以添加其他代码。。。" );[/align]
result = method.invoke( this.target ,
args); // 通过反射调用目标对象上的方法
[align=left] System. out.println("目标对象上的方法调用之后可以添加其他代码。。。" );[/align]

[align=left] return result;[/align]
[align=left] }[/align]

[align=left]}[/align]

ASP.Net+Android+IO开发.Net培训、期待与您交流!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: