代理模式的简单介绍及运用

代理模式(Proxy)

代理模式分为两种:一种是静态代理;一种是动态代理,因为静态代理存在的问题太多及不方便操作,现在使用的多数是动态代理,所以今天说的就是关于动态代理的一些基本.

  • 动态代理:指的是不用自己手动创建代理对象,通过Proxy类动态创建代理对象
  • 作用:拦截对真实对象的访问,对真实对象的功能进行增强
/*通过调用Proxy类的下面的方法创建代理对象*/
static Object newProxyInstrance(classLoader loader,interfaces,h)
/*方法的几个参数的含义
 - loader:传递的是真实对象的构造器
 - (方法创建代理对象的时候,内部是会生成一个代理类返回的,这个类需要知道被代理对象的一些具备的行为)
 - interfaces: 真实对象(被代理对象)实现的所有接口
 - (代理对象也需要具备被代理对象的功能)
 - h:回调处理对象(这个后面再讲,回调处理对象的作用就是为了拦截代理对象调用功能,再拦截功能后执行真实对象的功能,以至于做到代理对象调用功能的假象)


----------
回调处理对象:创建一个类去继承(invocationHandler接口),并且重写public Object invoke(Object proxy,Method method,Object[]args)方法
|-该方法的作用是,当每次代理对象调用的时候会触发该方法的调用,用于拦截方法,执行此方法
    |-proxy:代理对象
    |-method:对象调用的方法,拦截到方法
    |-agrs:代理对象调用方法时传递的参数
    |-返回值:一般返回真实对象执行后的结果

/*现有一个数据访问层类(StudentDao),类中提供了对学生进行增删改查的方法。
- 现有一个业务层类(StudentService),该类需要调用StudentDao类中定义好的方法对学生进行增删改查操作。
- 要求:在调用StudentDao方法之前要先判断用户是否有权限
  - 如果有权限则允许调用StudentDao方法,并在调用完StudentDao方法之后要记录日志。
  - 如果没有权限则不允许调用StudentDao方法。
  - **不允许修改StudentDao类中代码实现以上需求。**

- **数据访问层类StudentDao** */
public class StudentDao implements Dao<Student>{

    @Override
    public void save(Student t) {
        System.out.println("增加学生信息:" + t);
    }

    @Override
    public void delete(Student t) {
        System.out.println("删除学生信息:" + t);
    }

    @Override
    public void update(Student t) {
        System.out.println("更新学生信息:" + t);
    }

    @Override
    public Student find(int id) {
        System.out.println("查询学生信息");
        Student s =  new Student();
        System.out.println(s);
        return s;
    }
}
  • /* 业务层类StudentService */
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class StudentSerivce {
    public static void main(String[] args) {
        // 创建StudentDao对象
        // 被代理对象(真实对象)
        StudentDao stuDao = new StudentDao();
        // 创建学生对象
        Student stu = new Student();

        // 创建代理对象
        Dao proxy = (Dao)Proxy.newProxyInstance(StudentDao.class.getClassLoader(), 
                StudentDao.class.getInterfaces(), new InvocationHandler() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if(check(method)) {
                    // 如果有权限,则调用真实对象的方法
                    Object result = method.invoke(stuDao, args);
                    // 记录日志
                    log();

                    // 返回结果
                    return result;
                } else {
                    // 没有权限不调用真实对象的方法
                }
                return null;
            }
    /**
             * 记录日志
             */
            private void log() {
                System.out.println("记录日志");
            }

            /**
             * 检查是否有权限
             */
            public boolean check(Method method) {
                if(method.getName().equals("find")) return true;

                return false;
            }
                });

        // 通过代理对象调用方法
        proxy.save(stu);
        proxy.update(stu);
        proxy.delete(stu);
        Student s = (Student) proxy.find(1);
        System.out.println("ss = " + s);
    }

    // 自定义回调处理对象
    public static void test02(String[] args) {
        // 创建StudentDao对象
        // 被代理对象(真实对象)
        StudentDao stuDao = new StudentDao();
        // 创建学生对象
        Student stu = new Student();

        // 创建回调处理对象
        MyInvocationHandler handler = new MyInvocationHandler(stuDao);
        // 创建代理对象
        Dao proxy = (Dao)Proxy.newProxyInstance(StudentDao.class.getClassLoader(), 
                StudentDao.class.getInterfaces(), handler);

        // 通过代理对象调用方法
        proxy.save(stu);
        proxy.update(stu);
        proxy.delete(stu);
        Student s = (Student) proxy.find(1);
        System.out.println("ss = " + s);
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值