歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java代理模式簡單示例

靜態代理

1、新建一個接口,這個接口所提供的方法是關於數據庫操作的


public interface EmployeeDao {
    publicvoidupdateSalary();
}

2、建一個目標類實現這個接口,這個目標類是我們要進行的業務


public class EmployeeDaoImpl implements EmployeeDao {
    @Override
    publicvoidupdateSalary() {
        System.out.println("您的薪水又有更新");
    }
}

3、再建一個代理類,為目標對象提供一種代理,並以控制對這個對象的訪問。


public class EmployeeDaoProxy implements EmployeeDao{
    private EmployeeDao employeeDao;
    private Transaction transaction;
    publicEmployeeDaoProxy(EmployeeDao employeeDao,Transaction transaction) {
        this.employeeDao=employeeDao;
        this.transaction=transaction;
    }

    @Override
    publicvoidupdateSalary() {
        this.transaction.startTransaction();
        this.employeeDao.updateSalary();
        this.transaction.commit();
    }
    

由以上可知,代理模式的組成包括:目標接口(抽象角色),目標類(真實角色)和代理類(代理角色)。

4、代理類代理事務的處理,所以需要增加一個事務類


public class Transaction {
    publicvoidstartTransaction(){
        System.out.println("開啟事務");
    }
    publicvoidcommit(){
        System.out.print("事物提交");
    }
}

5、最後我們用一個test case來測試一下


import static org.junit.Assert.*;
import org.junit.Test;
public class ProxyTest {
    @Test
    publicvoidtest() {
        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;
    publicEmployeeInterceptor(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
    publicvoidtest() {
        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();
    }
}

最後看一下兩次執行的情況

開啟事務
您的薪水又有更新
事物提交

Copyright © Linux教程網 All Rights Reserved