歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java 代理模式應用

Java 代理模式應用

日期:2017/3/1 9:42:04   编辑:Linux編程

代理模式是一種效率非常高的模式,其定義如下:提供一種代理以控制對這個對象的訪問。

代理模式也叫委托模式,它是一項基本設計技巧。許多其他的設計模式,如狀態模式,策略模式,訪問者模式本質上是在更特殊的場合上采用了委托模式,代理模式在日常的使用中能夠提供更好的訪問控制。

1: 抽象角色

抽象主題角色類可以是一個接口,是一個普通的業務類型定義,無特殊要求。


2:具體角色

也叫被委托角色,這個角色才是真正干活的角色,是業務邏輯的具體執行者


3:代理主題角色


也叫做委托類,代理類,它負責對真實角色的應用,把所有抽象主題類定義的方法限制委托給真實角色實現,並且在真實主題角色

處理完畢前後做預處理和善後工作。

--------------------------------------分割線 --------------------------------------

編寫高質量代碼 改善Java程序的151個建議 PDF高清完整版 http://www.linuxidc.com/Linux/2014-06/103388.htm

Java 8簡明教程 http://www.linuxidc.com/Linux/2014-03/98754.htm

Java對象初始化順序的簡單驗證 http://www.linuxidc.com/Linux/2014-02/96220.htm

Java對象值傳遞和對象傳遞的總結 http://www.linuxidc.com/Linux/2012-12/76692.htm

Java對象序列化ObjectOutputStream和ObjectInputStream示例 http://www.linuxidc.com/Linux/2012-08/68360.htm

--------------------------------------分割線 --------------------------------------

定義一個接口:

package com.zzu.proxy;

public interface Movable {
void run();
}

實現類

package com.zzu.proxy;

public class Tank implements Movable{

@Override
public void run() {

try {
System.out.println("Tank is running.....");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

代理類

package com.zzu.proxy;

public class TankLogProxy implements Movable{

public TankLogProxy(Movable t) {
super();
this.t = t;
}
Movable t;

@Override
public void run() {
System.out.println("start log...");
t.run();
System.out.println("end log....");
}

}

另外一個代理類

package com.zzu.proxy;

public class TankTimeProxy implements Movable{

public TankTimeProxy(Movable t) {
super();
this.t = t;
}
Movable t;

@Override
public void run() {
System.out.println("time start...");
long start = System.currentTimeMillis();
t.run();
long end = System.currentTimeMillis();
System.out.println("time: "+(end - start));
}

}

client類

package com.zzu.proxy;

public class Client {
public static void main(String[] args) {
Movable m = new Tank();
TankLogProxy tlp = new TankLogProxy(m);
TankTimeProxy ttp = new TankTimeProxy(tlp);
Movable b = ttp;
b.run();
}
}

其實代理真正有意思的地方還是在於動態代理。下面說說動態代理的內在原理

動態代理:它和普通代理的不同地方在於,他在實現階段不用關心代理誰,而是在運行階段來指定哪一個對象。

它的實現實際上是通過JDK提供的 InvocationHandler,下面我們通過代碼的形式來研究一下動態代理的內在執行機制

我們先定義一個接口:

package dynamic;

public interface Subject {
// 業務操作
public void doSomething(String str);
//增加一個方法
public void doGirl();
}

接口的實現

package dynamic;

public class RealSubject implements Subject {

@Override
public void doSomething(String str) {
System.out.println("do some things -->>> " + str);
}

@Override
public void doGirl() {
System.out.println("to find a girl --->>>>> ");
}

}

動態代理的handler類

package dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 其中的InvocationHandler是JDK提供的動態代理的接口,其中的invoke方法是InvocationHandler必須實現的,它完成對真實方法的調用,即所有的真實方法調用都交給handler來接管
* @author Administrator
*
*/
public class MyInvocationHandler implements InvocationHandler {
// 被代理的對象
private Object target = null;

// 通過構造函數傳遞一個對象

public MyInvocationHandler(Object _obj) {
this.target = _obj;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(this.target, args);
}

}

動態代理類

package dynamic;

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

public class DynamicProxy<T> {
public static <T> T newProxyInstance(ClassLoader loader,
Class<?>[] interfaces, InvocationHandler h) {
// 尋找joinPoint連接點,AOP框架使用元數據定義
if (true) {
// 執行前一個通知
new BeforeAdvice().exec();
}
return (T) Proxy.newProxyInstance(loader, interfaces, h);

}
}

動態代理的場景類

package dynamic;

import java.lang.reflect.InvocationHandler;

public class Client {

/**
* @param args
*/
public static void main(String[] args) {
//定義一個主題
Subject subject = new RealSubject();
//定義一個handler
InvocationHandler handler = new MyInvocationHandler(subject);
//定義主題的代理
Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler);
//代理的行為,
proxy.doSomething("Finish");
proxy.doGirl();
}

}

動態代理實際上個人感覺和普通代理沒什麼區別,實際上的作用就是在不改變代碼的情況下增強或控制對象的行為,

動態代理實現代理的職責,業務邏輯實現相關的邏輯功能,兩者之間沒有必然的相互耦合的關系。

Copyright © Linux教程網 All Rights Reserved