1. 程式人生 > >java代理模式和動態代理

java代理模式和動態代理

1.代理模式
為什麼使用代理模式?
當處理實際的業務邏輯之前或者之後,想要處理一些別的事。比如吃飯是我真實要做的事情,但是在吃飯之前我必須要做飯,之後必須要洗碗。 做飯洗碗可以讓別人代做。

吃飯介面

package com.wch.api;

public interface IChifan {
	void Chifan();
}

吃飯實現

package com.wch.impl;

import com.wch.api.IChifan;

public class ChifanImpl implements IChifan {

	@Override
	public void Chifan() {
		System.out.println("吃飯");
	}

}

靜態代理類

package com.wch.impl;

import com.wch.api.IChifan;

public class ChifanProxy implements IChifan {
	private IChifan trueObject;
	public ChifanProxy(IChifan trueObject) {
		this.trueObject = trueObject;
	}

	@Override
	public void Chifan() {
		System.out.println("做飯");
		trueObject.Chifan();
		System.out.println("洗碗");
	}

}

測試

	@Test 
	public void staticProxy() {
		new ChifanProxy(new ChifanImpl()).Chifan();
	}

結果
在這裡插入圖片描述
從上面的例子可以看出,真正由我做的只有吃飯,而做飯洗碗都是別人做的。這體現了單一職責,真實物件的方法中只完成一個業務邏輯,而別的不影響真實業務邏輯的事情都交給代理來做。

如果IChifan介面有若干個方法,每一個前後都要加入新的業務邏輯呢?
如果不止是IChifan介面,其他介面的實現也需要加入新的業務邏輯呢?

2.動態代理
代理模式在編譯的時候已經有代理類存在,而動態代理模式的代理類在執行時才計算出來。
Proxy類:用來生成代理類。
InvocationHandler介面:當代理類執行方法時,呼叫該介面的invoke方法。

public class ProxyFactory {

	/**
	 * @param 要代理的類
	 * @return 代理類
	 */
	//代理
	//委託代理完成真實物件的業務邏輯   在代理實際邏輯前後加上代理所要做的業務邏輯
	//代理類需要知道:1.代理哪個類   2.要另外做的事
 	public static Object createProxy(Object o) {
		return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), o.getClass().getInterfaces(), new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println("做飯");
				System.out.println(proxy.getClass().getInterfaces()[0].getName());
				//用真實物件來執行業務邏輯
				Object methodReturn = null;
				try {
					methodReturn = method.invoke(o, args);
				}catch (Exception e) {
					System.out.println(e.getMessage());
				}
				System.out.println("洗碗");
				return methodReturn;
			}
		});
	}
}

測試

	@Test
	public void buildChifanProxy() {
		((IChifan)ProxyFactory.createProxy(new ChifanImpl())).Chifan();
	}

結果
在這裡插入圖片描述
如果有一些類需要代理做這些事情,而另一些需要代理幹那些事情,只需要實現多個 InvocationHandler介面即可。