码迷,mamicode.com
首页 > 编程语言 > 详细

18 java 代理模式 (转)

时间:2016-10-08 16:14:25      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

静态代理

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

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

开启事务
您的薪水又有更新
事物提交

18 java 代理模式 (转)

标签:

原文地址:http://www.cnblogs.com/yangh2016/p/5938758.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!