首先,上代碼
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自帶的動態代理實現方式,注意點是被代理的類必須實現了接口
當然,這只是給一個方法添加單個動態代理,下一篇再繼續講如何添加多個動態代理(非官方形式)