靜態(tài)代理
公共的接口(出租房子)
public interface Rent {
void rent();
}
真實的對象(被代理的對象 比如房東)
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房東要出租房子纷捞!");
}
}
代理對象(比如中介)
public class ProxyRent {
private Host host;
public void setHost(Host host) {
this.host = host;
}
public void invoke(){
// 這里先看房子再租房子
this.seeHouse();
host.rent();
}
// 實際業(yè)務(wù)中可能要增加一些其他業(yè)務(wù)后豫,但是又要不改變被代理類中的業(yè)務(wù)
// 比如我現(xiàn)在要增加一個中介帶看房的業(yè)務(wù)
private void seeHouse(){
System.out.println("中介帶看房子!");
}
}
最后就是真實的租房者
public class Client {
public static void main(String[] args) {
ProxyRent proxyRent = new ProxyRent();
Host host = new Host();
proxyRent.setHost(host);
proxyRent.invoke();
}
}
這里就是在沒有改變原代碼的前提下世澜,新增了一個帶看房子的業(yè)務(wù)。
靜態(tài)代理有比較大的局限性署穗,一個代理類只能代理一個被代理的類寥裂,那么當(dāng)被代理類比較多的時候,那么就需要些很多重復(fù)的代碼了案疲,在簡單的場景中使用比較合適抚恒,復(fù)雜的場景就可以使用下面的動態(tài)代理方式了。
動態(tài)代理有兩種使用比較廣泛的方式實現(xiàn)络拌,他們的底層原理其實差不多俭驮,一種是JDK原生的方式,另一種就是CGLib,下面的實例采用JDK的方式實現(xiàn)混萝。
先寫出兩個接口遗遵,以便等會兒做演示
public interface Rent {
void rent();
}
public interface UserService {
void add();
void delete();
void update();
void query();
}
然后時它們的實現(xiàn)類,也就是需要被代理的類
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房東要出租房子逸嘀!");
}
}
public class User implements UserService{
@Override
public void add() {
System.out.println("新增一個用戶车要!");
}
@Override
public void delete() {
System.out.println("刪除一個用戶!");
}
@Override
public void update() {
System.out.println("修改一個用戶崭倘!");
}
@Override
public void query() {
System.out.println("查詢一個用戶翼岁!");
}
}
然后就是比較關(guān)鍵的一個類了,我們需要實現(xiàn)InvocationHandler接口
public class ProxyInvocationHandler implements InvocationHandler {
// 這里采用Object類型司光,就可以代理不同的類了琅坡。
private Object target;
public void setTarget(Object target) {
this.target = target;
}
// 生成得到代理類
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.log(method.getName());
Object result = method.invoke(target, args);
return result;
}
// 新增其他業(yè)務(wù)
public void log(String type){
System.out.println(type + "操作。");
}
}
最后測試一下
public class Client {
public static void main(String[] args) {
// 代理User對象
// User user = new User();
//
// ProxyInvocationHandler handler = new ProxyInvocationHandler();
//
// handler.setTarget(user);
// UserService proxy = (UserService) handler.getProxy();
//
// proxy.delete();
// 代理Host對象
Host host = new Host();
ProxyInvocationHandler handler = new ProxyInvocationHandler();
handler.setTarget(host);
Rent proxy = (Rent) handler.getProxy();
proxy.rent();
}
}