靜態代理 1、新建一個介面,這個介面所提供的方法是關於資料庫操作的 2、建一個目標類實現這個介面,這個目標類是我們要進行的業務 3、再建一個代理類,為目標對象提供一種代理,並以控制對這個對象的訪問。 由以上可知,代理模式的組成包括:目標介面(抽象角色),目標類(真實角色)和代理類(代理角色)。 4、 ...
靜態代理
1、新建一個介面,這個介面所提供的方法是關於資料庫操作的
public interface EmployeeDao {
public void updateSalary();
}
2、建一個目標類實現這個介面,這個目標類是我們要進行的業務
public class EmployeeDaoImpl implements EmployeeDao {
@Override
public void updateSalary() {
System.out.println("您的薪水又有更新");
}
}
3、再建一個代理類,為目標對象提供一種代理,並以控制對這個對象的訪問。
public class EmployeeDaoProxy implements EmployeeDao{
private EmployeeDao employeeDao;
private Transaction transaction;
public EmployeeDaoProxy(EmployeeDao employeeDao,Transaction transaction) {
this.employeeDao=employeeDao;
this.transaction=transaction;
}
@Override
public void updateSalary() {
this.transaction.startTransaction();
this.employeeDao.updateSalary();
this.transaction.commit();
}
由以上可知,代理模式的組成包括:目標介面(抽象角色),目標類(真實角色)和代理類(代理角色)。
4、代理類代理事務的處理,所以需要增加一個事務類
public class Transaction {
public void startTransaction(){
System.out.println("開啟事務");
}
public void commit(){
System.out.print("事物提交");
}
}
5、最後我們用一個test case來測試一下
import static org.junit.Assert.*;
import org.junit.Test;
public class ProxyTest {
@Test
public void test() {
EmployeeDao target = new EmployeeDaoImpl();
Transaction transaction = new Transaction();
EmployeeDao proxy = new EmployeeDaoProxy(target,transaction);
proxy.updateSalary();
}
}
執行情況
開啟事務
您的薪水又有更新
事物提交
假設上面的例子中的介面不只一個方法,或是不只一個介面要用到代理,上面的靜態代理的代碼就太過繁瑣和冗餘,所以就出現了jdk的動態代理。
動態代理
同樣以上面的例子做示例
1和2中的介面和目標類的編寫以及4中的事務處理是相同的,在3中,我們引入攔截器的概念,攔截器是實現動態性的核心
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/*
* 攔截器
* 引入目標類和事務
* 通過構造器給目標函數和事務賦值
* 填充invoke方法
*
*/
public class EmployeeInterceptor implements InvocationHandler{
private Object target;
private Transaction transaction;
public EmployeeInterceptor(Object target, Transaction transaction) {
this.target = target;
this.transaction = transaction;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
this.transaction.startTransaction();
method.invoke(this.target, args);
this.transaction.commit();
return null;
}
}
同樣在test case中作出修改
import static org.junit.Assert.*;
import java.lang.reflect.Proxy;
import org.junit.Test;
public class ProxyTest1 {
@Test
public void test() {
EmployeeDao target = new EmployeeDaoImpl();
Transaction transaction = new Transaction();
EmployeeInterceptor interceptor = new EmployeeInterceptor(target,transaction);
EmployeeDao employeeDao = (EmployeeDao)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor);
employeeDao.updateSalary();
}
}
最後看一下兩次執行的情況
開啟事務
您的薪水又有更新
事物提交