靜態代理
比如說有一個添加的方法需要記錄日誌,但又不想修改添加的方法,我們可以採用靜態代理,這樣的好處是業務類只要關注自己的業務邏輯,保證了重用性,其他的業務如記錄日誌,權限檢查等交給其他的業務類去做
定義接口
public interface User {
public void add();
public void delete();
}
被代理的類 要實現User接口
public class UserImp implements User {
@Override
public void add() {
System.out.println("添加用戶...");
}
@Override
public void delete() {
System.out.println("刪除用戶...");
}
}
代理類 UserProxy 要和被代理的類UserImp實現同一個User接口
public class UserProxy implements User {
private UserImp userImp;
public UserProxy(UserImp userImp) {
this.userImp = userImp;
}
@Override
public void add() {
System.out.println("開始記錄日誌");
userImp.add();
System.out.println("記錄日誌結束");
}
@Override
public void delete() {
System.out.println("開始記錄日誌");
userImp.delete();
System.out.println("記錄日誌結束");
}
}
測試類
public class Test {
public static void main(String[] args) {
UserProxy proxy = new UserProxy(new UserImp());
proxy.add();
System.out.println("---------------");
proxy.delete();
}
}
控制檯輸出
開始記錄日誌
添加用戶...
記錄日誌結束
---------------
開始記錄日誌
刪除用戶...
記錄日誌結束
靜態代理要爲每個類創建代理類,如果類很多,我們需要創建很多代理類,而且每個方法(add(),delete())都要手動添加日誌功能,比較麻煩,所以可以使用動態代理針對某個功能(如日誌,權限等)提供一個代理類。
動態代理
繼續使用上面的User接口和UserImp類,新加動態代理的類LogProxy,動態代理的類要實現InvocationHandler接口
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class LogProxy implements InvocationHandler {
// 目標對象
private Object obj;
public Object bind(Object obj) {
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), //
obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object object = null;
System.out.println("開始記錄日誌");
object = method.invoke(obj, args);
System.out.println("記錄日誌結束");
return object;
}
}
測試類
public class Test {
public static void main(String[] args) {
LogProxy proxy = new LogProxy();
User user = (User) proxy.bind(new UserImp());
user.add();
System.out.println("---------------");
user.delete();
}
}
控制檯輸出
開始記錄日誌
添加用戶...
記錄日誌結束
---------------
開始記錄日誌
刪除用戶...
記錄日誌結束