java之代理模式

1.模式定義

       代理模式是指其他對象使用代理來控制對對象的訪問。

2.代理分類

        靜態代理分爲普通代理和強制代理兩種。通用模式是Subject接口,以及實現這個接口的兩個類:RealSubject類,Proxy代理類(傳入RealSubjct的實例)

        普通代理,是指用戶無需知道RealSubject,只要知道代理並調用即可。這時需要將通用模式稍微修改。RealSubject的構造函數參數加入Subject類型的代理。Proxy類中直接new RealSubjct(this)  這時在客戶端直接new Proxy類,即可調用RealSubject的方法。

        強制代理,是指用戶直接調用RealSubject,但是返回的是Proxy的實例。在通用模式的基礎上,Subject接口添加一個getProxy()方法的接口,RealSubject實現Subject的getProxy的方法,加入Proxy的對象,如果爲空,直接new Proxy(),然後對於RealSubject判斷有沒有代理,沒有代理的話拋出異常。這樣客戶端直接new  RealSubject().getProxy()即可返回代理,並通過該代理,調用RealSubject中的方法。

        動態代理:動態代理應用於AOP中。有兩種實現方式,一種是JDK實現的,針對實現接口的類。一種是CGLIB實現的,是對類的子類實現代理,所以不能對final的類實現動態代理。

        JDK動態代理

               1.需要實現InvocationHandler接口的類,該類需要傳入Subject,重寫invoke方法,即實現對RealSubject的動態調用。

                2.需要動態返回代理。Proxy.getNewProxy(classLoder,interfaces,handler) 返回的代理即可調用RealSubject中的方法。如果需要在切入點進行對象的功能增強,可在此方法之前進行攔截和過濾。

3.JDK動態代理實例

package com.sogou.proxy_test;

public interface IAdvice {
	public void exec();

}

package com.sogou.proxy_test;

public class BeforeAdvice implements IAdvice{

	public void exec() {
		// TODO Auto-generated method stub
		System.out.println("這是前置通知並且被執行");
		
	}

}
package com.sogou.proxy_test;

public interface Subject {
	public void  dosomething(String str);

}
package com.sogou.proxy_test;

public class RealSubject implements Subject{

	public void dosomething(String str) {
		// TODO Auto-generated method stub
		System.out.println("do something ---- >> "+str);
		
	}

}
package com.sogou.proxy_test;

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

public class MyInvocationHandler implements InvocationHandler{
	Object object=null;
	public  MyInvocationHandler(Object o){
		object=o;
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// TODO Auto-generated method stub
		return method.invoke(this.object, args);
	}

}
package com.sogou.proxy_test;

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){
		if (true) {
			(new BeforeAdvice()).exec();
		}
		return (T) Proxy.newProxyInstance(loader, interfaces, h);
	}

}
package com.sogou.proxy_test;

public class Client {
	public static void main(String[] args){
		Subject subject=new RealSubject();
		MyInvocationHandler h=new MyInvocationHandler(subject);
		Subject proxy=DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), h);
	    proxy.dosomething("yeah");
	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章