初识动态代理-jdk,CGLIB,拦截器

本文详细介绍了动态代理的概念及其在Java中的实现方式,包括JDK动态代理和CGLIB动态代理的具体代码示例,帮助读者理解如何在不修改原始代码的基础上增加新功能。

像代理服务器一样,你想访问真实服务器不直接访问而是通过一个中转站,代理服务器访问;
调用真实对象的一个方法不直接调用,而是通过产生的一个代理对象调用。
人家是动态编程,需要在原来的方法的功能基础上再添加一些功能,而不用改变这个方法的签名,原来调用这个方法的类依然能正常工作。搜索
比如,现在要把一段文本发送给另一个人,普通方法是 void send(File a),现在我们弄出个特性,就像 Spring AOP 那样,在 send 之前给这个 a 压缩一下。原来的程序没有压缩功能,现在我们需要添加的话而不改变原来所有的代码的话就得用类似 AOP 这样的代码来处理。

代理分为两步:第一,先产生一个代理对象,并和真实的对象关联起来,产生代理关系;第二,实现代理对象的代理逻辑方法,这里一般都是由一个实现一个接口做的,JDK动态代理用java.lang.reflect.InvocationHandler这个接口;CGLIB用org.springframework.cglib.proxy.MethodInterceptor接口。

首先是JDK动态代理的代码:因为JDK动态代理必须借助一个接口才能实现产生代理对象:
定义一个接口

public interface Youplando {
public void dosomething(String string);
}
package 设计模式;

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

class Youwanttodo implements Youplando{

    @Override
    public void dosomething(String string) {
        // TODO Auto-generated method stub
        System.out.println("我想做"+string);
    }
}

/**
 * @author Administrator
 * JDK代理分为两步:
 * 1.代理对象和真实对象简历代理关系
 * 2.实现代理对象的代理逻辑方法
 */
class JDKproxyExample implements InvocationHandler{
    //真实对象
    private Object target = null;

    /**
     * JDK代理第一步:~~~~~
     * newProxyInstance的三个参数:第一个是target本身的类加载器;
     * 第二个是代理对象下挂在哪些接口下
     * 第三个是实现方法逻辑的代理类,这里就是JDKproxyExample这个当前类,必须实现InvocationHandler接口,重写invoke方法
     * @param target 真实的对象
     * @return 代理对象
     */
    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance
                (target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    /**
     * JDK代理第二步:~~~~~
     * @param proxy 代理对象,
     * @param method 调用的方法
     * @param args[] 方法参数列表
     * @return Object 代理结果
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //相当于反射调用了真实对象的方法
        System.out.println("调用真实方法前哦");
        Object object = method.invoke(target, args);
        System.out.println("调用真实方法后哦");
        return object;
    }
}

public class JDKproxy {
    public static void main(String[] args) {
        //先实例化JDKproxyExample,用它来代理
        JDKproxyExample jdk = new JDKproxyExample();
        //真实对象
        Youwanttodo realinstance = new Youwanttodo();
        //产生代理对象proxy;
        Youplando proxy = (Youplando) jdk.bind(realinstance);
        //代理对象调用方法
        proxy.dosomething("我我想做的");
    }
}

CGLIB动态代理,不需要接口,但是是spring的代理包:

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
package Test;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

class Iwangtodo{
    public void Iwangtodo(String string) {
        System.out.println("i really wang to be"+string);
    }
}

class CglibProxyExample implements MethodInterceptor{

    /**
     * 还是第一步!!!!!!!!!!
     * 生成CGLIB代理对象
     * @param cls 真实对象
     * @return 代理对象
     */
    public Object getProxy(Class cls) {
        //CGLIB enhancer增强类对象
        Enhancer enhancer = new Enhancer();
        //设置增强类型
        enhancer.setSuperclass(cls);
        //定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法
        enhancer.setCallback(this);
        //返回代理对象
        return enhancer.create();
    }

    /**
     * 还是第二部!!!!!!!!!
     * 生成CGLIB代理对象
     * @param proxy 代理对象
     * @param method 调用方法
     * @param arg 方法参数
     * @param methodproxy 方法代理
     * @return 代理结果
     */
    public Object intercept(Object proxy, Method method, Object[] arg,
            MethodProxy methodproxy) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("调用真实方法前");
        Object result = methodproxy.invokeSuper(proxy, arg);
        System.out.println("调用真实方法后");
        return result;
    }
}

public class CGLIBproxy {
    public static void main(String[] args) {
        //代理实例
        CglibProxyExample cglib = new CglibProxyExample();
        //用代理实例产生一个代理对象
        Iwangtodo iwangtodo = (Iwangtodo) cglib.getProxy(Iwangtodo.class);
        //代理对象调用方法
        iwangtodo.Iwangtodo("攻城狮!!");
    }
}

拦截器代码:

package 设计模式;

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

/*实现了拦截器接口*/
class InterceptorImp implements Interceptor{
    @Override
    public boolean before(Object proxy, Object target, Method method, Object[] args) {
        // TODO Auto-generated method stub
        System.out.println("反射前");
        return false;
    }

    @Override
    public void around(Object proxy, Object target, Method method, Object[] args) {
        // TODO Auto-generated method stub
        System.out.println("取代了被代理对象的方法");
    }

    @Override
    public void after(Object proxy, Object target, Method method, Object[] args) {
        // TODO Auto-generated method stub
        System.out.println("反射后");
    }

}

/*被调用方法的类,实现了接口*/
class Youwanttodo implements Youplando{
    @Override
    public void dosomething(String string) {
        // TODO Auto-generated method stub
        System.out.println("我想做"+string);
    }
}

/*JDK动态代理中使用拦截器*/
public class InterceptorJdkProxy implements InvocationHandler {

    private Object target;//真实对象
    private String interceptorClass = null;//拦截器全限定名

    //传入真实对象,和拦截器名字
    public InterceptorJdkProxy(Object target,String interceptorClass) {
        // TODO Auto-generated constructor stub
        this.target = target;
        this.interceptorClass = interceptorClass;
    }

    /*第一步,取得代理对象*/
    public static Object bind(Object target,String interceptorClass) {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
                target.getClass().getInterfaces(), new InterceptorJdkProxy(target,interceptorClass));
    }

    /*第二步实现代理逻辑方法*/
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        if (interceptorClass==null) {
            //如果没有拦截器,调用真实对象的方法了
            return method.invoke(target, args);
        }
        //返回代理结果
        Object result = null;
        /*生成拦截器*/
        Interceptor interceptor = (Interceptor) Class.forName(interceptorClass).newInstance();
        if (interceptor.before(proxy, target, method, args)) {
            //before为true;反射方法
            result = method.invoke(target, args);
        }else {
            //before为false
            interceptor.around(proxy, args, method, args);
        }
        //后置方法
        interceptor.after(proxy, target, method, args);
        return result;
    }

    public static void main(String[] args) {
        //代理对象
        Youplando proxy = (Youplando) InterceptorJdkProxy.bind(new Youwanttodo(), "设计模式.InterceptorImp");
        proxy.dosomething("a goodboy");
    }

}
代码转载自:https://pan.quark.cn/s/a4b39357ea24 本文重点阐述了利用 LabVIEW 软件构建的锁相放大器的设计方案及其具体实施流程,并探讨了该设备在声波相位差定位系统中的实际运用情况。 锁相放大器作为一项基础测量技术,其核心功能在于能够精确锁定微弱信号的频率参数并完成相关测量工作。 在采用 LabVIEW 软件开发的锁相放大器系统中,通过计算测量信号与两条参考信号之间的互相关函数,实现对微弱信号的频率锁定,同时输出被测信号的幅值信息。 虚拟仪器技术是一种基于计算机硬件平台的仪器系统,其显著特征在于用户可以根据实际需求自主设计仪器功能,配备虚拟化操作界面,并将测试功能完全由专用软件程序实现。 虚拟仪器系统的基本架构主要由计算机主机、专用软件程序以及硬件接口模块等核心部件构成。 虚拟仪器最突出的优势在于其功能完全取决于软件编程,用户可以根据具体应用场景灵活调整系统功能参数。 在基于 LabVIEW 软件开发的锁相放大器系统中,主要运用 LabVIEW 软件平台完成锁相放大器功能的整体设计。 LabVIEW 作为一个图形化编程环境,能够高效地完成虚拟仪器的开发工作。 借助 LabVIEW 软件,可以快速构建锁相放大器的用户操作界面,并且可以根据实际需求进行灵活调整和功能扩展。 锁相放大器系统的关键构成要素包括测量信号输入通道、参考信号输入通道、频率锁定处理单元以及信号幅值输出单元。 测量信号是系统需要检测的对象,参考信号则用于引导系统完成对测量信号的频率锁定。 频率锁定处理单元负责实现测量信号的锁定功能,信号幅值输出单元则负责输出被测信号的幅值大小。 在锁相放大器的实际实现过程中,系统采用了双路参考信号输入方案来锁定测量信号。 通过分析两路参考信号之间的相...
边缘计算环境中基于启发式算法的深度神经网络卸载策略(Matlab代码实现)内容概要:本文介绍了在边缘计算环境中,利用启发式算法实现深度神经网络任务卸载的策略,并提供了相应的Matlab代码实现。文章重点探讨了如何通过合理的任务划分与调度,将深度神经网络的计算任务高效地卸载到边缘服务器,从而降低终端设备的计算负担、减少延迟并提高整体系统效率。文中涵盖了问题建模、启发式算法设计(如贪心策略、遗传算法、粒子群优化等可能的候选方法)、性能评估指标(如能耗、延迟、资源利用率)以及仿真实验结果分析等内容,旨在为边缘智能计算中的模型推理优化提供可行的技术路径。; 适合人群:具备一定编程基础,熟悉Matlab工具,从事边缘计算、人工智能、物联网或智能系统优化方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①研究深度神经网络在资源受限设备上的部署与优化;②探索边缘计算环境下的任务卸载机制与算法设计;③通过Matlab仿真验证不同启发式算法在实际场景中的性能表现,优化系统延迟与能耗。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注算法实现细节与仿真参数设置,同时可尝试复现并对比不同启发式算法的效果,以深入理解边缘计算中DNN卸载的核心挑战与解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

obession

觉得有用可以打赏咖啡一杯~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值