Java动态代理

代理模式

  • 静态代理 : 代理类是提前写好的
  • 动态代理 : 代理类是动态生成的

静态代理中一个真实角色就会产生一个代理对象,当代理对象多了之后,代码量会翻倍,开发效率会降低,所以要使用动态代理
动态代理可以代理多个类,代理的是接口!

动态代理:

  1. 基于接口的动态代理—Jdk动态代理
  2. 基于类的动态代理—cglib动态代理

下面主要讲的是JDK动态代理,需要用到 InvocationHandler 接口 ,Method 类 ,
Proxy

**

1. InvocationHandler接口

**
InvocationHandler接口叫做调用处理器,负责完成调用目标方法,并增强功能,通过代理对象(Proxy创建)执行目标接口中的方法,会把方法的调用分派给调用处理器(InvocationHandler)的实现类,执行实现类中的invoke方法,我们要把加强的功能写在invoke方法中.

 /**
     * 处理代理实例上的方法  并返回结果
     * @param proxy:代表生成的代理对象  调用该方法的代理实例
     * @param method:代表目标方法
     * @param args:目标方法的参数
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)

2. Method类

Method 类
上述invoke()方法的第二个参数为 Method 类对象,该类有一个方法也叫 invoke(),可以调用
目标方法。这两个 invoke()方法,虽然同名,但无关。

public Object invoke ( Object obj, Object... args) 
obj:表示目标对象
args:表示目标方法参数,就是其上一层 invoke 方法的第三个参数

3 . Proxy 类

通 过 JDK 的 java.lang.reflect.Proxy 类 实 现 动 态 代 理 , 会 使 用 其 静 态 方 法
newProxyInstance(),依据目标对象、业务接口及调用处理器三者,自动生成一个动态代理对象

public static newProxyInstance ( ClassLoader loader, Class<?>[] interfaces, 
InvocationHandler handler) 
loader:目标类的类加载器,通过目标对象的反射可获取
interfaces:目标类实现的接口数组,通过目标对象的反射可获取
handler:调用处理器。

4. 步骤

1、新建一个接口,作为目标接口
2、为接口创建一个实现类,是目标类 (到这边都和之前的代码步骤是一样的)

3、创建类实现InvocationHandler 接口,调用目标方法并增加其他功能代码
4、创建动态代理对象,使用 Proxy.newProxyInstance()方法,并把返回值强制转为接口类型

package com.kuang.demo3;

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

public class ProxyInvocationHandler implements InvocationHandler {
    
    //被代理的接口可是任意形式
    private Object target;
    public void setTarget(Object target) {
        //使用构造方法传入目标对象,给目标对象提供代理功能
        this.target = target;
    }
    
    //生成得到代理类  这里将生成代理类自己接封装进了该类中
    public Object getProxy(){
        /**
         * this在这就是调用处理器对象
         */
        Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);
        return proxy;
    }


    /**
     * 处理代理实例上的方法  并返回结果
     * @param proxy:代表生成的代理对象  调用该方法的代理实例
     * @param method:代表目标方法
     * @param args:目标方法的参数
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //在该方法中可写增强的功能
        System.out.println("增强了....");
        Object result = method.invoke(target, args);

        return result;
    }
}

import com.kuang.demo3.ProxyInvocationHandler;
import com.kuang.seivice.UserService;
import com.kuang.seivice.UserServiceImpl;

public class MyTest {
    public static void main(String[] args) {

        UserService userService = new UserServiceImpl();
        ProxyInvocationHandler pih = new ProxyInvocationHandler();\
        //设置要代理的对象
        pih.setTarget(userService);
        //动态生成代理类
        UserService proxy = (UserService) pih.getProxy();
        proxy.delect();
    }
}


对于偏底层的对象还不太懂可以看下这个,就是怎么调用的invoke问题

在这里插入图片描述

图出处

https://blog.csdn.net/ShewMi/article/details/78108705?utm_source=app&app_version=4.5.2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值