java中的靜態代理和動態代理,入門整理


靜態代理和動態代理主要解決的問題是:在直接訪問對象時帶來的問題,其目的就是為其他對象提供一個代理以控制對某個對象的訪問。代理類負責為委托類預處理消息,過濾消息並轉發消息,以及進行消息被委托類執行后的后續處理。

靜態代理在感覺上和裝飾設計模式很像

  1)、在代理類中實現被代理類實現的所有接口,這樣保證了被代理類所能實現的方法,代理類也能實現,保證了兩邊行為的一致性,代理類就能轉型為被代理類,當作被代理類處理。而代理中有被代理類的對象,這樣,在代理類的內部實現接口方法時就能調用被代理類的方法,從而進行對被代理類的封裝。

簡單的示范:

package cn.edu.cjl;

public interface Subject {
	public void replace();
}

  

package cn.edu.cjl;

public class RealSubject implements Subject{

	@Override
	public void replace() {
		// TODO Auto-generated method stub
		System.out.println("real subject...");
	}

}

  

package cn.edu.cjl;

public class daili implements Subject {
	RealSubject subject;
	@Override
	public void replace() {
		System.out.println("before...");
		if(subject==null){
			subject=new RealSubject();
		}
		subject.replace();
		System.out.println("after...");
	}

}

  

package cn.edu.cjl;

public class Client {
	public static void main(String[] args) {
		Subject subject=new daili();
		subject.replace();
	}
}

 代碼中定義接口Subject,真實的實現類是RealSubject,但是在在主方法中調用的是daili類,在daili類中同樣實現了Subject接口,但是真實上調用的是RealSubject類的方法。這就是靜態代理。

  靜態代理可以解決直接訪問類方法帶來的問題,但是本身也有問題,就是當大量的使用靜態代理時類的個數將雙倍的增加,不利於程序的管理。

 

 

動態代理使用了反射技術,一個代理類可以為任意類提供代理。

  代理類必須實現InvocationHandler接口,對代理實例調用方法時,將對方法調用進行編碼並將其指派到它的代理程序的 invoke 方法。

  invoke方法運用反射技術,通過java.lang.reflect.Proxy類中提供的靜態方法 newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)  返回一個指定接口的代理類實例,該接口可以將方法調用指派到指定的調用處理程序,也就是代理類實現的InvocationHandler接口中的invoke方法中,這個方法的各個參數的意思是

ClassLoader loader:類加載器,定義代理類的類加載器,可以任意指定。

Class<?>[] interfaces: 被代理類所實現的所有接口的class數組,可以用class對象的getInterfaces()方法得到。

InvocationHandler h:實現了InvocationHandler接口的對象。

簡單的事例:

package cn.edu.cjl.proxy;

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

public class proxy implements InvocationHandler {
	private Object object;
	public proxy(Object obj){
		this.object=obj;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("before");
		Object resultObject= method.invoke(object, args);
		System.out.println("after");
		return resultObject;
	}

}

  

package cn.edu.cjl.proxy;

import java.lang.reflect.Proxy;

public class Client {
	public static void main(String[] args) {
		Subject subject = null;
		RealSubject rSubject = new RealSubject();
		proxy proxy = new proxy(rSubject);
		subject = (Subject) Proxy.newProxyInstance(Client.class
				.getClassLoader(), rSubject.getClass().getInterfaces(), proxy);
		subject.replace();
	}
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM