經典三層框架初識(二)---Spring 3.1靜態代理
我麼在學習框架的時候我們知道,像這些增刪改查的業務都應該處於事務的環境下.事務最適合新增的這一層是業務邏輯層.也就是我們所謂的service.我們現在新建一個java專案.在src下頂一個service的包.裡面有個UserService介面
package service;
public interface UserService {
void addUser();
void deleteUser();
}
service包下有個impl的子包,裡面是UserService的實現類UserServiceImpl
package service.impl; import service.UserService; public class UserServiceImpl implements UserService { /* * 這裡正常應該是呼叫dao的方法,這裡我們就用輸出語句代替了 */ @Override public void addUser() { System.out.println("新增使用者"); } @Override public void deleteUser() { System.out.println("刪除使用者"); } }
UserServiceImpl的程式碼我們前面已經寫成這個樣子了,現在我希望新增事務的管理.事務我們知道:在UserServiceImpl裡面增刪改查的程式碼執行之前應該有開始事務,結束有提交事務 .現在想模擬一下這個過程.希望在UserServiceImpl裡的增刪改查的程式碼執行之前,都用列印"開啟事務"來代替,結束列印"提交事務".
在不考慮spring之前,我們想要實現上面的過程,應該如何實現的呢?
首先我們考慮到,這些事務的新增和提交不能寫在UserServiceImpl這類裡面.咱們每個類都應該遵從單一原則.UserServiceImpl這個類只是處理增刪改查,它與所謂的在不在事務裡面沒有關係.為了實現上面的要求,我們下面來介紹一下代理:
代理:
物件訪問前後實現預處理,過濾等處理.代理可以在不改動目標物件的基礎上,增加其他額外的功能(擴充套件功能)。
代理模式:這裡我們主要說靜態代理
靜態代理:編譯期間為每個委託類建立代理類
現在我們的委託類是UserServiceImpl,現在需要代理類來代理UserServiceImpl,首先代理類肯定要知道UserServiceImpl這個委託類裡面有怎樣的方法.這裡說一下使用靜態代理的一個前:需要我們的代理類和委託類實現同一個介面或者是繼承相同父類。
那我們現在寫一下代理的程式碼,先在service先建立一個子包proxy.裡面建立代理類UserServiceProxy
package service.proxy; import service.UserService; /* * 代理類 */ public class UserServiceProxy implements UserService { /* * 這個代理類並不是真正做事的. */ UserService service; public UserServiceProxy(UserService service) { this.service = service; } @Override public void addUser() { System.out.println("開啟事務"); service.addUser(); System.out.println("提交事務"); } @Override public void deleteUser() { System.out.println("開啟事務"); service.deleteUser(); System.out.println("提交事務"); } }
下面我們在測試類裡測試一下:
package test;
import service.UserService;
import service.impl.UserServiceImpl;
import service.proxy.UserServiceProxy;
public class Test {
@org.junit.Test
public void test(){
//代理物件,把目標物件傳給代理物件,建立代理關係
UserService proxy = new UserServiceProxy(new UserServiceImpl());
//執行的是代理的方法,實際上是呼叫了委託類的方法
proxy.addUser();
proxy.deleteUser();
}
}
上面就是我們所說的靜態代理.
可以實現在不修改目標物件的基礎上,對目標物件的功能進行擴充套件。
但是由於代理物件需要與目標物件實現一樣的介面,所以會有很多代理類,類太多.同時,一旦介面增加方法,目標物件與代理物件都要維護.而且類似上面的每一個方法都要新增開啟事務和提交事務的程式碼,冗餘太多了.
那如果解決上面的出現的問題,就是我們後面要講的:可以使用動態代理方式來解決。