本文源碼: "GitHub·點這裡" || "GitEE·點這裡" 一、生活場景 1、場景描述 在電商高速發展的今天,快遞的數量十分龐大,甚至出現了快遞代理行業,簡單的說就是快遞的主人沒有時間收快遞,會指定一個快遞的代收點,比如快遞櫃,快遞驛站等,然後等有時間的時候再過去取,下麵使用代碼對這個場景進 ...
本文源碼:GitHub·點這裡 || GitEE·點這裡
一、生活場景
1、場景描述
在電商高速發展的今天,快遞的數量十分龐大,甚至出現了快遞代理行業,簡單的說就是快遞的主人沒有時間收快遞,會指定一個快遞的代收點,比如快遞櫃,快遞驛站等,然後等有時間的時候再過去取,下麵使用代碼對這個場景進行簡單的描述。
2、場景圖解
3、源碼實現
public class C01_InScene {
public static void main(String[] args) {
/*自己收快遞的測試方式*/
GetExpress getExpress = new GetExpress();
getExpress.sureInfo();
getExpress.signName("張三");
/*代收快遞的測試方式*/
ExpressAct getUser = new GetExpress();
ExpressAct getProxy = new ProxyExpress(getUser);
getProxy.sureInfo();
getProxy.signName("李四");
}
}
/**
* 接收一個快遞的動作介面:確認信息,簽名
*/
interface ExpressAct{
void sureInfo();
void signName(String name);
}
/**
* 定義一個類接收快遞:自己去拿快遞
*/
class GetExpress implements ExpressAct{
@Override
public void sureInfo() {
System.out.println("請確認你的個人信息!");
}
@Override
public void signName(String name) {
System.out.println("你的名字是:"+name);
}
}
/**
* 定義一個類接收快遞:找人代領快遞
*/
class ProxyExpress implements ExpressAct{
private ExpressAct expressAct=null;
public ProxyExpress(ExpressAct expressAct){
this.expressAct = expressAct;
}
@Override
public void sureInfo() {
this.expressAct.sureInfo();
}
@Override
public void signName(String name) {
this.expressAct.signName(name);
}
}
二、代理模式
1、概念描述
代理模式是對象的結構模式。代理模式給某一個對象提供一個代理對象,並由代理對象控制對原對象的引用。所謂代理,就是一個對象代表另一個對象執行相應的動作程式。而代理對象可以在客戶端和目標對象之間起到中介的作用。
2、模式圖解
3、核心角色
- 抽象對象角色
聲明目標對象和代理對象的共同介面。
- 目標對象角色
定義了代理對象所代表的目標對象。
- 代理對象角色
代理對象內部含有目標對象的引用,可以在任何時候操作目標對象;代理對象提供一個與目標對象相同的介面,可以在任何時候替代目標對象。代理對象通常在客戶端調用傳遞給目標對象之前或之後,執行某個操作,而不是單純地將調用傳遞給目標對象,AOP編程就是基於這個思想。
4、源碼實現
public class C02_Proxy {
public static void main(String[] args) {
AbstractObject object = new ProxyObject();
object.operation();
}
}
/**
* 抽象對象角色
*/
abstract class AbstractObject{
public abstract void operation();
}
/**
* 目標對象角色
*/
class TargetObject extends AbstractObject{
@Override
public void operation() {
System.out.println("Target Method Run...");
}
}
/**
* 代理對象角色
*/
class ProxyObject extends AbstractObject{
TargetObject targetObject = new TargetObject();
@Override
public void operation() {
System.out.println("Method Before...");
targetObject.operation();
System.out.println("Method After...");
}
}
三、JDK動態代理
基於JDK動態代理方式實現AOP切麵編程。
1、代碼實現
public class C03_JdkProxy {
public static void main(String[] args) {
BookService bookService = BookAopProxyFactory.createService() ;
System.out.println(bookService.getBook());
}
}
class BookAspect {
public void before (){
System.out.println("Method Before ...");
}
public void after (){
System.out.println("Method After ...");
}
}
interface BookService {
String getBook () ;
}
class BookServiceImpl implements BookService {
@Override
public String getBook() {
System.out.println("目標方法【getBook】被執行");
return "高性能MySQL";
}
}
class BookAopProxyFactory {
public static BookService createService() {
// 目標類
final BookService bookService = new BookServiceImpl() ;
// 切麵類
final BookAspect bookAspect = new BookAspect();
/*
* 代理類:將目標類(切入點)和 切麵類(通知) 結合
*/
BookService proxyBookService = (BookService) Proxy.newProxyInstance(
BookAopProxyFactory.class.getClassLoader(),
bookService.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
// 前執行
bookAspect.before();
// 執行目標類的方法
Object obj = method.invoke(bookService, args);
// 後執行
bookAspect.after();
return obj;
}
});
return proxyBookService ;
}
}
四、幾種常見代理
- 防火牆代理
內網通過代理穿透防火牆,實現對公網的訪問。
- 緩存代理
為了緩解網站併發壓力,在請求資料庫資源時,先取緩存中代理的數據,如果緩存未命中,再到資料庫取數據,然後緩存取到的數據。
- 遠程代理
遠程對象的本地代理對象,通過它可以把遠程對象當本地對象調用 。遠程代理通過網路和調用的遠程對象進行信息交互 。
- 同步代理
主要使用在多線程編程中,完成多線程間同步工作。
五、源代碼地址
GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent