1. 程式人生 > >經典三層框架初識(二)---Spring 3.1靜態代理

經典三層框架初識(二)---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();
	}
}

上面就是我們所說的靜態代理.

可以實現在不修改目標物件的基礎上,對目標物件的功能進行擴充套件。

但是由於代理物件需要與目標物件實現一樣的介面,所以會有很多代理類,類太多.同時,一旦介面增加方法,目標物件與代理物件都要維護.而且類似上面的每一個方法都要新增開啟事務和提交事務的程式碼,冗餘太多了.

那如果解決上面的出現的問題,就是我們後面要講的:可以使用動態代理方式來解決。