静态代理设计模式
package com.learn.service;/*** user 服務(wù)層* @author Leon.Sun**/
public interface UserService {/*** 在add方法里面怎么進(jìn)行處理呢* 這里是接口不能寫(xiě)方法體的*/public void add();
}
package com.learn.service.impl;import com.learn.service.UserService;//user 服務(wù)層
/*** 在這里寫(xiě)一個(gè)實(shí)現(xiàn)出來(lái)* 實(shí)現(xiàn)一下UserService這個(gè)接口* @author Leon.Sun**/
public class UserServiceImpl implements UserService {/*** spring 事務(wù)封裝呢? aop技術(shù)* 實(shí)現(xiàn)完了之后講一下方法* Spring他是怎樣進(jìn)行封裝的呢* Spring的事務(wù)是怎么封裝的呢* 他其實(shí)是采用AOP技術(shù)* 在方法之前和之后做個(gè)攔截* 在方法之前開(kāi)啟事務(wù)* 在方法運(yùn)行完畢之后就提交事務(wù)* 就是這樣的* 為了提高代碼的復(fù)用性* 我們把重復(fù)的代碼抽取出來(lái)* 放在代理類(lèi)里去實(shí)現(xiàn)* 你看看我之前也講過(guò)的* 我們是不是要寫(xiě)一個(gè)代碼類(lèi)對(duì)象* */public void add() {System.out.println("開(kāi)啟事務(wù).....");/*** 打印日志* 就是往數(shù)據(jù)庫(kù)添加數(shù)據(jù)....* 在添加之前和之后要加一個(gè)事務(wù)處理* 但是如果以后每個(gè)方法都是這樣去開(kāi)啟事務(wù)那就非常麻煩*/System.out.println("往數(shù)據(jù)庫(kù)添加數(shù)據(jù)...");System.out.println("提交事務(wù).....");}}
package com.learn.day02;import com.learn.service.UserService;
import com.learn.service.impl.UserServiceImpl;public class Test001 {public static void main(String[] args) {/*** 我們有一個(gè)UserServiceImpl實(shí)現(xiàn)* 正常情況下我們new一個(gè)UserServiceImpl* 這邊是有一個(gè)接口UserService* */UserService userService = new UserServiceImpl();/*** 這個(gè)時(shí)候我們做一個(gè)調(diào)用* 就可以實(shí)現(xiàn)這樣的一個(gè)功能* 開(kāi)啟事務(wù)* 當(dāng)我往數(shù)據(jù)庫(kù)添加完了以后* 就可以提交事務(wù)* 這是最基本的*/userService.add();
// UserServiceProxy userServiceProxy = new UserServiceProxy(userService);
// userServiceProxy.add();}}
package com.learn.service;/*** user 服務(wù)層* @author Leon.Sun**/ public interface UserService {/*** 在add方法里面怎么進(jìn)行處理呢* 這里是接口不能寫(xiě)方法體的*/public void add(); } package com.learn.service.impl;import com.learn.service.UserService;//user 服務(wù)層 /*** 在這里寫(xiě)一個(gè)實(shí)現(xiàn)出來(lái)* 實(shí)現(xiàn)一下UserService這個(gè)接口* @author Leon.Sun**/ public class UserServiceImpl implements UserService {/*** spring 事務(wù)封裝呢? aop技術(shù)* 實(shí)現(xiàn)完了之后講一下方法* Spring他是怎樣進(jìn)行封裝的呢* Spring的事務(wù)是怎么封裝的呢* 他其實(shí)是采用AOP技術(shù)* 在方法之前和之后做個(gè)攔截* 在方法之前開(kāi)啟事務(wù)* 在方法運(yùn)行完畢之后就提交事務(wù)* 就是這樣的* 為了提高代碼的復(fù)用性* 我們把重復(fù)的代碼抽取出來(lái)* 放在代理類(lèi)里去實(shí)現(xiàn)* 你看看我之前也講過(guò)的* 我們是不是要寫(xiě)一個(gè)代碼類(lèi)對(duì)象* */public void add() { // System.out.println("開(kāi)啟事務(wù).....");/*** 打印日志* 就是往數(shù)據(jù)庫(kù)添加數(shù)據(jù)....* 在添加之前和之后要加一個(gè)事務(wù)處理* 但是如果以后每個(gè)方法都是這樣去開(kāi)啟事務(wù)那就非常麻煩*/System.out.println("往數(shù)據(jù)庫(kù)添加數(shù)據(jù)..."); // System.out.println("提交事務(wù).....");}} package com.learn.proxy;import com.learn.service.UserService;//靜態(tài)代理設(shè)計(jì)模式 /*** 代理類(lèi)要么你去反射生成* 要么通過(guò)字節(jié)碼技術(shù)* @author Leon.Sun**/ public class UserServiceProxy {/*** 寫(xiě)完了之后的時(shí)候*/private UserService userService;/*** 通過(guò)構(gòu)造函數(shù)* 寫(xiě)構(gòu)造函數(shù)的時(shí)候* 傳入他需要代理的接口出來(lái)* 這個(gè)你們有沒(méi)有印象* 這個(gè)是我在很早就講過(guò)的* 有沒(méi)有印象我們?cè)谥v字節(jié)碼技術(shù)的時(shí)候* 使用字節(jié)碼技術(shù)創(chuàng)建類(lèi)* 有沒(méi)有印象* 我是不是講過(guò)一個(gè)例子* 創(chuàng)建一個(gè)類(lèi)出來(lái)* 像AOP底層就是把這一層* 怎么做呢* 我不想去創(chuàng)建代理對(duì)象* 我們采用動(dòng)態(tài)的* 我們?nèi)斯?chuàng)建代理對(duì)象的情況下* 他要要么通過(guò)反射機(jī)制* 要么通過(guò)字節(jié)碼技術(shù)* 創(chuàng)建一個(gè)虛擬的代理類(lèi)對(duì)象* 就是這樣的* 只不過(guò)是內(nèi)存里面我們線(xiàn)程看不到* 這個(gè)我就不細(xì)說(shuō)* 這個(gè)原理我大體介紹一下* 有一部分人可能之前沒(méi)有學(xué)* 我之前講代理設(shè)計(jì)模式講的特別深* 把原理都扯出來(lái)了* 代理設(shè)計(jì)模式ASM是干嘛用的* 其實(shí)ASM就是做字節(jié)碼的新增修改* 他和動(dòng)態(tài)代理有什么區(qū)別* 靜態(tài)代理是什么* 我會(huì)演示的* 動(dòng)態(tài)代理是沒(méi)有代理類(lèi)這一層的* 為什么你想想* 如果我這個(gè)時(shí)候有幾千個(gè)類(lèi)需要代理* 那你是不是需要寫(xiě)幾千個(gè)代理類(lèi)對(duì)象* 這樣代碼寫(xiě)的太復(fù)雜了* 我們需要一個(gè)動(dòng)態(tài)的代理對(duì)象* 我們?nèi)藶榭床坏? 通過(guò)虛擬技術(shù)生成出來(lái)* 一般是字節(jié)碼技術(shù)* 或者反射技術(shù)* 就是這樣的* 沒(méi)關(guān)系我待會(huì)給你演示* 靜態(tài)代理你理不理解* 我給你們總結(jié)一下* 動(dòng)態(tài)代理馬上要講的* * * * @param userService*/public UserServiceProxy(UserService userService) {/*** 通過(guò)構(gòu)造函數(shù)把它傳進(jìn)來(lái)* */this.userService = userService;}/*** 我在代理類(lèi)里面也實(shí)現(xiàn)一下* */public void add() {/*** 這里開(kāi)啟事務(wù)*/System.out.println("靜態(tài)代理 開(kāi)啟事務(wù)");userService.add();/*** 提交事務(wù)*/System.out.println("靜態(tài)代理 提交事務(wù)");}} package com.learn.day02;import com.learn.proxy.UserServiceProxy; import com.learn.service.UserService; import com.learn.service.impl.UserServiceImpl;/*** 這個(gè)其實(shí)就叫做靜態(tài)代理設(shè)計(jì)模式* 一般AOP里面不會(huì)用靜態(tài)代理設(shè)計(jì)模式* 每個(gè)類(lèi)都需要寫(xiě)代理類(lèi)類(lèi)對(duì)象* 這樣寫(xiě)的話(huà)性能不會(huì)很好* 這樣寫(xiě)的話(huà)代碼也會(huì)比較多* 不能復(fù)用* * @author Leon.Sun**/ public class Test001 {public static void main(String[] args) {/*** 我們有一個(gè)UserServiceImpl實(shí)現(xiàn)* 正常情況下我們new一個(gè)UserServiceImpl* 這邊是有一個(gè)接口UserService* */UserService userService = new UserServiceImpl();/*** 這個(gè)時(shí)候我們做一個(gè)調(diào)用* 就可以實(shí)現(xiàn)這樣的一個(gè)功能* 開(kāi)啟事務(wù)* 當(dāng)我往數(shù)據(jù)庫(kù)添加完了以后* 就可以提交事務(wù)* 這是最基本的*/ // userService.add();/*** 這個(gè)時(shí)候我們用的時(shí)候就不一樣了* 要這樣用了* new一下代理類(lèi)對(duì)象UserServiceProxy* 把我們的service傳進(jìn)去* 拿到了我們的代理類(lèi)對(duì)象* */UserServiceProxy userServiceProxy = new UserServiceProxy(userService);/*** 然后通過(guò)代理類(lèi)對(duì)象調(diào)用我們的方法* 然后會(huì)打印靜態(tài)代理開(kāi)啟事務(wù)* 靜態(tài)代理提交事務(wù)* */userServiceProxy.add();}}
package com.learn.service;/*** user 服務(wù)層* @author Leon.Sun**/ public interface UserService {/*** 在add方法里面怎么進(jìn)行處理呢* 這里是接口不能寫(xiě)方法體的*/public void add(); } package com.learn.service.impl;import com.learn.service.UserService;//user 服務(wù)層 /*** 在這里寫(xiě)一個(gè)實(shí)現(xiàn)出來(lái)* 實(shí)現(xiàn)一下UserService這個(gè)接口* @author Leon.Sun**/ public class UserServiceImpl implements UserService {/*** spring 事務(wù)封裝呢? aop技術(shù)* 實(shí)現(xiàn)完了之后講一下方法* Spring他是怎樣進(jìn)行封裝的呢* Spring的事務(wù)是怎么封裝的呢* 他其實(shí)是采用AOP技術(shù)* 在方法之前和之后做個(gè)攔截* 在方法之前開(kāi)啟事務(wù)* 在方法運(yùn)行完畢之后就提交事務(wù)* 就是這樣的* 為了提高代碼的復(fù)用性* 我們把重復(fù)的代碼抽取出來(lái)* 放在代理類(lèi)里去實(shí)現(xiàn)* 你看看我之前也講過(guò)的* 我們是不是要寫(xiě)一個(gè)代碼類(lèi)對(duì)象* */public void add() { // System.out.println("開(kāi)啟事務(wù).....");/*** 打印日志* 就是往數(shù)據(jù)庫(kù)添加數(shù)據(jù)....* 在添加之前和之后要加一個(gè)事務(wù)處理* 但是如果以后每個(gè)方法都是這樣去開(kāi)啟事務(wù)那就非常麻煩*/System.out.println("往數(shù)據(jù)庫(kù)添加數(shù)據(jù)..."); // System.out.println("提交事務(wù).....");}} package com.learn.proxy;import com.learn.service.UserService;//靜態(tài)代理設(shè)計(jì)模式 /*** 代理類(lèi)要么你去反射生成* 要么通過(guò)字節(jié)碼技術(shù)* @author Leon.Sun**/ public class UserServiceProxy {/*** 寫(xiě)完了之后的時(shí)候*/private UserService userService;/*** 通過(guò)構(gòu)造函數(shù)* 寫(xiě)構(gòu)造函數(shù)的時(shí)候* 傳入他需要代理的接口出來(lái)* 這個(gè)你們有沒(méi)有印象* 這個(gè)是我在很早就講過(guò)的* 有沒(méi)有印象我們?cè)谥v字節(jié)碼技術(shù)的時(shí)候* 使用字節(jié)碼技術(shù)創(chuàng)建類(lèi)* 有沒(méi)有印象* 我是不是講過(guò)一個(gè)例子* 創(chuàng)建一個(gè)類(lèi)出來(lái)* 像AOP底層就是把這一層* 怎么做呢* 我不想去創(chuàng)建代理對(duì)象* 我們采用動(dòng)態(tài)的* 我們?nèi)斯?chuàng)建代理對(duì)象的情況下* 他要要么通過(guò)反射機(jī)制* 要么通過(guò)字節(jié)碼技術(shù)* 創(chuàng)建一個(gè)虛擬的代理類(lèi)對(duì)象* 就是這樣的* 只不過(guò)是內(nèi)存里面我們線(xiàn)程看不到* 這個(gè)我就不細(xì)說(shuō)* 這個(gè)原理我大體介紹一下* 有一部分人可能之前沒(méi)有學(xué)* 我之前講代理設(shè)計(jì)模式講的特別深* 把原理都扯出來(lái)了* 代理設(shè)計(jì)模式ASM是干嘛用的* 其實(shí)ASM就是做字節(jié)碼的新增修改* 他和動(dòng)態(tài)代理有什么區(qū)別* 靜態(tài)代理是什么* 我會(huì)演示的* 動(dòng)態(tài)代理是沒(méi)有代理類(lèi)這一層的* 為什么你想想* 如果我這個(gè)時(shí)候有幾千個(gè)類(lèi)需要代理* 那你是不是需要寫(xiě)幾千個(gè)代理類(lèi)對(duì)象* 這樣代碼寫(xiě)的太復(fù)雜了* 我們需要一個(gè)動(dòng)態(tài)的代理對(duì)象* 我們?nèi)藶榭床坏? 通過(guò)虛擬技術(shù)生成出來(lái)* 一般是字節(jié)碼技術(shù)* 或者反射技術(shù)* 就是這樣的* 沒(méi)關(guān)系我待會(huì)給你演示* 靜態(tài)代理你理不理解* 我給你們總結(jié)一下* 動(dòng)態(tài)代理馬上要講的* * * * @param userService*/public UserServiceProxy(UserService userService) {/*** 通過(guò)構(gòu)造函數(shù)把它傳進(jìn)來(lái)* */this.userService = userService;}/*** 我在代理類(lèi)里面也實(shí)現(xiàn)一下* */public void add() {/*** 這里開(kāi)啟事務(wù)*/System.out.println("靜態(tài)代理 開(kāi)啟事務(wù)");userService.add();/*** 提交事務(wù)*/System.out.println("靜態(tài)代理 提交事務(wù)");}} package com.learn.day02;import com.learn.proxy.UserServiceProxy; import com.learn.service.UserService; import com.learn.service.impl.UserServiceImpl;/*** 這個(gè)其實(shí)就叫做靜態(tài)代理設(shè)計(jì)模式* 一般AOP里面不會(huì)用靜態(tài)代理設(shè)計(jì)模式* 每個(gè)類(lèi)都需要寫(xiě)代理類(lèi)類(lèi)對(duì)象* 這樣寫(xiě)的話(huà)性能不會(huì)很好* 這樣寫(xiě)的話(huà)代碼也會(huì)比較多* 不能復(fù)用* * @author Leon.Sun**/ public class Test001 {public static void main(String[] args) {/*** 我們有一個(gè)UserServiceImpl實(shí)現(xiàn)* 正常情況下我們new一個(gè)UserServiceImpl* 這邊是有一個(gè)接口UserService* */UserService userService = new UserServiceImpl();/*** 這個(gè)時(shí)候我們做一個(gè)調(diào)用* 就可以實(shí)現(xiàn)這樣的一個(gè)功能* 開(kāi)啟事務(wù)* 當(dāng)我往數(shù)據(jù)庫(kù)添加完了以后* 就可以提交事務(wù)* 這是最基本的*/ // userService.add();/*** 這個(gè)時(shí)候我們用的時(shí)候就不一樣了* 要這樣用了* new一下代理類(lèi)對(duì)象UserServiceProxy* 把我們的service傳進(jìn)去* 拿到了我們的代理類(lèi)對(duì)象* */UserServiceProxy userServiceProxy = new UserServiceProxy(userService);/*** 然后通過(guò)代理類(lèi)對(duì)象調(diào)用我們的方法* 然后會(huì)打印靜態(tài)代理開(kāi)啟事務(wù)* 靜態(tài)代理提交事務(wù)* */userServiceProxy.add();}}
?
總結(jié)