疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java代理模式简单示例


 

   

  静态代理

  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();

  }

  }

  最后看一下两次执行的情况

  开启事务

  您的薪水又有更新

  事物提交