java動態代理記錄

首先,上代碼

BaseJDKProxy.java

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

public abstract class BaseJDKProxy implements InvocationHandler{
	
	protected Object target;

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

	/**
	 * 獲取目標對象的代理對象
	 * @return 代理對象
	 */
	@SuppressWarnings("unchecked")
	public <T> T getProxy() {
		return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
				target.getClass().getInterfaces(), this);
	}
	
	public void before(){
		System.out.println("方法執行前操作.......");
	}
	
	public void after(){
		System.out.println("方法執行後操作.......");
	}
	
	public void err(Exception e){
		// 獲取拋出異常信息的代碼行數
		System.out.println("調用類:" + Thread.currentThread().getStackTrace()[2].getFileName() + ",行數:" + Thread.currentThread().getStackTrace()[2].getLineNumber());
		System.out.println("方法執行異常,異常信息:" + e);
	}
}

然後是JDKProxy.java

import java.lang.reflect.Method;

public class JDKProxy extends BaseJDKProxy {

	public JDKProxy(Object target) {
		super(target);
		// TODO Auto-generated constructor stub
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		try{
			before();
			System.out.println("-------------------------------------------");
			// 獲取代理的方法執行後的返回結果
			// 執行方法(此處不能直接寫proxy,原因自己試試就知道了)
			Object result = method.invoke(target, args);
			System.out.println("該方法返回值爲:" + result.toString() + "\n-------------------------------------------");
			after();
			return result;
		} catch (Exception e) {
			err(e);
		}
		return null;
	}

}
其次就是代理類以及入口相關

public class JDKProxyTest {
	public static void main(String[] args) {
		LoginService login = new Login();
		JDKProxy proxy = new JDKProxy(login);
		LoginService loginProxy = proxy.getProxy();
		loginProxy.login();
	}
	
}

class Login implements LoginService{
	@Override
	public void login() {
		System.out.println("登錄成功");
	}
}

interface LoginService{
	void login();
}

運行後輸出日誌如下:

運行輸出:

方法執行前操作.......
-------------------------------------------
登錄成功
調用類:JDKProxy.java,行數:24
方法執行異常,異常信息:java.lang.NullPointerException

修改代碼爲無異常代碼輸出:

方法執行前操作.......
-------------------------------------------
登錄成功
該方法返回值爲:方法無返回
-------------------------------------------
方法執行後操作.......

當然,判斷方法是否有返回值之類的可以自行在method中尋找,提供了很多種方法,反射相關,這裏不提及

以上便是JDK自帶的動態代理實現方式,注意點是被代理的類必須實現了接口

當然,這只是給一個方法添加單個動態代理,下一篇再繼續講如何添加多個動態代理(非官方形式)



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