详解 动态代理

(请观看本人博文 —— 《详解 反射机制》


动态代理

概述

  • 代理:本来应该自己做的事情,却请了别人来做被请的人就是代理对象
    举例:春季回家买票让人代买
  • 动态代理:在程序运行过程中产生的这个对象
    而程序运行过程中产生对象,其实就是本人刚才反射讲解的内容,
    所以,动态代理其实就是通过反射来生成一个代理

特点

字节码 随用随创建随用随加载

作用

不修改源码的基础上对方法增强

分类

基于接口的动态代理
基于子类的动态代理
注意:JDK给我们提供的动态代理,只能对接口进行代理.

如何创建代理对象

使用Proxy类中的newProxyInstance方法

创建代理对象的要求

被代理类最少实现一个接口,如果没有则不能使用

其实,动态代理,主要应用了两个方法:

  1. Proxy类中的方法创建动态代理类对象:
    public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
    参数
    loader: 类加载器
    interfaces: 接口对应的一个Class数组
    InvocationHandler: 这个其实就是要代理对象所做的事情的一个类的封装

  1. 而这个方法,最终会调用InvocationHandler接口的方法:
    InvocationHandler Object invoke(Object proxy,Method method,Object[] args)
    作用:执行被代理对象的任何接口方法都会经过该方法
    参数
    proxy:代理对象的引用
    method:当前执行的方法
    args:当前执行方法所需的参数
    返回值:和被代理对象方法有相同的返回值

那么,现在,本人就来展示下通过这些知识点,来编写一个动态代理小工具,并做下使用展示:

首先是 动态代理小工具

package edu.youzg.about_reflact.core;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyUtil {

    //获取代理对象的方法
    //参数:就是被代理对象(目标对象)
    //返回值:代理对象
    public static IUserDao getProxy(IUserDao userDao) {
        IUserDao obj = (IUserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //执行目标对象的任何接口方法都会经过该方法
               Object result = null;
                if (method.getName().equals("delete")) {    //这里仅仅对该接口的delete()方法做了增加了几个步骤
                    System.out.println("权限的校验 "); //增强的代码
                    result = method.invoke(userDao);//让目标对象中方法执行
                    System.out.println("记录日志"); //增强的代码
                } else {
                    result = method.invoke(userDao);//让目标对象中方法执行
                }
                return result;
            }
        });

        return obj; //返回代理对象
    }

}

现在,本人来给出一个测试接口:

package edu.youzg.about_reflact.core;

public interface IUserDao {
    void insert();
    void delete();
    void update();
    void query();
}

本人再来给出一个测试接口的实现类:

package edu.youzg.about_reflact.core;

public class UserDaoImpl implements IUserDao{

    @Override
    public void insert() {

        System.out.println("添加一个用户");

    }

    @Override
    public void delete() {

        System.out.println("删除用户");

    }

    @Override
    public void update() {
        System.out.println("修改用户");

    }
    
    @Override
    public void query() {
        System.out.println("查询用户");
    }

}

现在,本人来给出一个测试类,来展示下这个小工具的使用:

package edu.youzg.about_reflact.core;

import com.sun.deploy.net.proxy.ProxyUtils;

public class Test {

    public static void main(String[] args) throws Exception {
        IUserDao userDao = new UserDaoImpl();
        //我们采用动态代理的模式,在不修改原有代码的情况下,对类中的方法进行增强(增加一些额外功能)
        //通过我们写的工具类,来获取一个代理对象
        IUserDao proxy = ProxyUtil.getProxy(userDao);
        proxy.insert();
        System.out.println("----------------------");
        proxy.delete();
        System.out.println("----------------------");
        proxy.update();
        System.out.println("----------------------");
        proxy.query();
    }

}

那么,本人来展示下运行结果
在这里插入图片描述
可以看到,只有删除操作,多了几个步骤。


(本人 反射机制 总集篇博文链接:https:////www.cnblogs.com/codderYouzg/p/12419061.html

猜你喜欢

转载自www.cnblogs.com/codderYouzg/p/12419087.html