為了理解Spring中的核心之一AOP,學習該代理模式
靜態代理模式的好處:
可以使真實角色的操作更加純粹!不用去關注一些公共的業務
公共業務發生擴展時,方便集中管理!
代理模式的缺點
一個真實角色就會產生一個代理角色,代碼量會翻倍,開發效率會變低
靜態代理
案例1:租房
-
圖示

-
需要實作的介面
// 租房案例
public interface Rent {
void rent();
}
- 真實物件:房東
// 房東
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房東想出租房子");
}
}
- 代理物件:中介
public class HostProxy implements Rent {
private Host host;
public HostProxy() {
}
public HostProxy(Host host) {
this.host = host;
}
@Override
public void rent() {
host.rent();
check();
sign();
}
public void check() {
System.out.println("中介帶租客看房");
}
public void sign() {
System.out.println("中介與租客簽合同");
}
}
- 客戶租房
public class Client {
public static void main(String[] args) {
// 被代理的物件:要出租房屋的房東
Host host = new Host();
// 代理物件:中介,
// 除了幫助房東完成出租任務,還會進行看房、簽合同操作
HostProxy hostProxy = new HostProxy(host);
// 租客不需要面對房東,找到中介即可完成租房
hostProxy.rent();
}
}
案例2:助理老師上課
- 需要實作的介面
public interface ITeacherDao {
void teach();
}
- 真實物件:老師
public class TeacherDao implements ITeacherDao {
@Override
public void teach() {
System.out.println("老師授課中......");
}
}
- 代理物件:助理老師
public class TeacherDaoProxy implements ITeacherDao {
private ITeacherDao target;
public TeacherDaoProxy(ITeacherDao target) {
this.target = target;
}
@Override
public void teach() {
System.out.println("授課前準備");
target.teach();
System.out.println("準備");
}
}
- 助理老師上課
public class Client {
public static void main(String[] args) {
// 被代理物件:原來的老師
TeacherDao teacherDao = new TeacherDao();
// 代理物件:助理老師
TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);
teacherDaoProxy.teach();
}
}
動態代理的好處:
可以使真實角色的操作更加純粹!不用去關注一些公共的業務
公共業務發生擴展時,方便集中管理!
一個動態代理類代理的是一個介面,一般就是對應的一類業務
只要是實作了同一個介面,一個動態代理類就可以代理多個類
動態代理
動態代理中的代理物件由代理工廠生成
案例:助理老師sayHello
- 需要實作的介面
public interface ITeacherDao {
void sayHello(String name);
}```
- 老師
public class TeacherDao implements ITeacherDao {
@Override
public void sayHello(String name) {
System.out.println("hello " + name + "!");
}
}
- 核心:代理工廠
public class ProxyFactory {
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
/*
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
ClassLoader loader 被代理物件,即目標物件的類加載器
Class<?>[] interfaces 被代理物件,即目標物件實作的介面
InvocationHandler h 執行被代理物件的方法時,會把當前執行的被代理物件方法作為引數傳入
*/
public Object getProxyObject() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("兩人遇到了");
Object returnValue = https://www.cnblogs.com/0x3fcy/archive/2022/02/21/method.invoke(target, args);
System.out.println("打招呼結束");
return returnValue;
}
});
}
}
- 測驗一下
public class Client {
public static void main(String[] args) {
// 創建被代理物件
TeacherDao teacherDao = new TeacherDao();
// 給被代理物件創建代理物件
ITeacherDao proxyObject = (ITeacherDao) new ProxyFactory(teacherDao).getProxyObject();
proxyObject.sayHello("Tom");
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/430233.html
標籤:其他
上一篇:DDD-領域驅動設計簡談
