Java怎么通过动态代理实现一个简单的拦截器操作

Java怎么通过动态代理实现一个简单的拦截器操作

一、代理

在使用动态代理实现拦截器之前我们先简单了解一下什么Java的代理。

代理,顾名思义,就是不直接操作被代理(下面都用目标对象称呼,听起来舒服一些)对象,而是通过一个代理对象去间接的使用目标对象中的方法。代理分为两种模式,一种是静态代理,一种是动态代理。接下来先写一个静态代理的例子。

无论是静态代理还是动态代理,目标对象(target)都要实现一个接口(interface),注意,如果使用cglib提供的代理,则不必实现接口,而是通过子类去实现,暂不讨论该种方式。

(1)先定义一个接口

public interface IUserDao {    void save();}

(2)定义目标对象(target)

public class UserDaoImpl implements IUserDao {    public void save() {        System.out.println("--------已经保存数据---------");    }}

(3)定义代理对象

public class UserDaoProxy implements IUserDao { private IUserDao target;//将目标对象放到代理对象中 public UserDaoProxy(IUserDao target){  this.target = target;  } public void save() {     System.out.println("------开始事务------");            target.save();     System.out.println("-------提交事务------");    }}

测试一下:

public class Test {public static void main(String[] args){    IUserDao userDao = new UserDaoImpl();    UserDaoProxy proxy = new UserDaoProxy(userDao);    proxy.save();//通过代理对象调用save方法    }}

输出结果为:

——开始事务——
——–已经保存数据———

——-提交事务——

这种方式有一个问题,就是代理对象必须也要实现被代理对象所实现的同一个接口,这就出现了严重的耦合。所以,下面使用一种改进的方式,即动态代理(jdk代理)。

动态代理方式也需要目标对象(target)实现一个接口

(1)定义一个接口(IUserDao)

(2)定义一个目标对象类(UserDaoImpl)

(3)创建动态代理类

public class ProxyFactory {    //维护一个目标对象    private Object target;     public ProxyFactory(Object target) {        this.target = target;    }     //给目标对象生成代理对象    public Object getProxyInstance() {        System.out.println("----target class---" + target.getClass());        System.out.println("----target interfaces---" +            target.getClass().getInterfaces());         return Proxy.newProxyInstance(target.getClass().getClassLoader(),            target.getClass().getInterfaces(),            new InvocationHandler() {                public Object invoke(Object proxy, Method method, Object[] args)                    throws Throwable {                    System.out.println("----开始事务2-----");                     //执行目标对象方法                    Object returnValue = method.invoke(target, args);                    System.out.println("----提交事务2----");                     return returnValue;                }            });    }}

测试一下:

public class Test {    public static void main(String[] args) {        //目标对象        IUserDao target = new UserDao();        System.out.println(target.getClass());         //给目标对象创建代理对象        IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();        System.out.println("----proxy----:" + proxy.getClass());        proxy.save();        proxy.delete();    }}

输出结果:

class com.jd.pattern.proxy.dynamicProxy.UserDao
—-target class—class com.jd.pattern.proxy.dynamicProxy.UserDao
—-target interfaces—[Ljava.lang.Class;@1fb3ebeb
—-proxy—-:class com.sun.proxy.$Proxy0
—-开始事务2—–
—–保存完成——
—-提交事务2—-
—-开始事务2—–
—-删除完成—-

—-提交事务2—-

二、使用动态代理实现一个简单的拦截器

既然是采用动态代理的方式,那么肯定会有 接口、目标类、代理类,再加一个拦截器

1、定义一个接口

public interface BusinessFacade {    void doSomething();}

2、定义一个目标对象

public class BusinessClass implements BusinessFacade {    public void doSomething() {        System.out.println("在业务组件BusinessClass中调用doSomething方法");    }}

3、创建拦截器

public class InterceptorClass {    public void before() {        System.out.println("在InterceptorClass中调用方法:before()");    }     public void after() {        System.out.println("在InterceptorClass中调用方法:after()");    }}

4、创建代理

public class DynamicProxyHandler {    //声明被代理对象    private Object target;    //创建拦截器    InterceptorClass interceptor = new InterceptorClass();    //动态生成一个代理对象,并绑定被代理类和代理处理器    public Object getProxyInstance(final Object target) {        this.target = target;        return Proxy.newProxyInstance(target.getClass().getClassLoader(),            target.getClass().getInterfaces(),            new InvocationHandler() {                public Object invoke(Object proxy, Method method, Object[] args)                    throws Throwable {                    interceptor.before();                    Object result = method.invoke(target, args);                    interceptor.after();                    return result;                }            });    }}

测试一下:

public class Test {    public static void main(String[] args) {        //创建动态代理工具        DynamicProxyHandler proxyHandler = new DynamicProxyHandler();        //创建业务组件        BusinessFacade target = new BusinessClass();        //获取代理对象        BusinessFacade proxy = (BusinessFacade) proxyHandler.getProxyInstance(target);        //通过代理对象调用目标对象方法        proxy.doSomething();    }}

输出结果:

在InterceptorClass中调用方法:before()
在业务组件BusinessClass中调用doSomething方法
在InterceptorClass中调用方法:after()

读到这里,这篇“Java怎么通过动态代理实现一个简单的拦截器操作”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。

文章标题:Java怎么通过动态代理实现一个简单的拦截器操作,发布者:亿速云,转载请注明出处:https://worktile.com/kb/p/20902

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
亿速云亿速云认证作者
上一篇 2022年8月27日 下午4:41
下一篇 2022年8月27日 下午4:42

相关推荐

  • 怎么进行Apache Dubbo反序列化漏洞的分析

    简介 Dubbo是阿里巴巴公司开源的一个高性能优异的服务框架,使得应用可通过高性能的RPC实现服务的输出和输入功能,可以和Spring框架无缝集成。它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。 概述 2020年06月23日, Apache Dubbo 官…

    2022年9月10日
    35400
  • id是html的属性吗

    id属于html。id是html中的一个全局属性,可以用来配置所有元素共有行为、可以用在任何一个元素身上。id属性用于赋予某个标签少数的名称(标识符),当使用CSS或者JavaScript来操作这个标签时,就可以通过id属性来找到这个标签。 本教程操作环境:windows7系统、CSS3&&…

    2022年9月24日
    29200
  • windows xbox商店常见问题怎么解决

    xbox商店常见问题解决方法: 1、Xbox商店其实就是微软win10商店(Microsoft Store)。 2、我们可以直接在菜单中打开Microsoft Store,进行游戏的查看等。 3、我们也可以直接在搜索栏中搜索Xbox,然后打开“Xbox 控制台小帮手” 4、我们能够在侧栏目中点击“商…

    2022年9月22日
    29000
  • windows驱动精灵usb驱动如何安装

    驱动精灵usb驱动安装方法: 1、打开进入驱动精灵点击“一键体检”。 2、等待扫描计算机。 3、扫描完成后点击“驱动程序”。 4、下拉找到USB,选择“下载”。 5、下载完成后点击“安装”。 6、等待安装即可。 7、最后点击“完成”即可完成安装。 读到这里,这篇“windows驱动精灵usb驱动如何…

    2022年9月13日
    21400
  • 电脑0xc0000011如何解决

    0xc0000011修复方法: 方法一: 1、首先我们需要查看是否是软件问题,开机时按住“F8”直到进入系统修复界面。 2、接着在其中选择“最后一次正确的配置”回车进入。 3、如果我们无法进入系统,那么说明就不是安装的软件或驱动等问题。 方法二: 1、这时候就需要采用系统盘进行修复了。 2、如果我们…

    2022年9月18日
    24000
  • Mysql锁的内部实现机制是什么

    注:所列举代码皆出自Mysql-5.6 虽然现在关系型数据库越来越相似,但其背后的实现机制可能大相径庭。实际使用方面,因为SQL语法规范的存在使得我们熟悉多种关系型数据库并非难事,但是有多少种数据库可能就有多少种锁的实现方法。 Microsoft Sql Server2005之前只提供页锁,直到20…

    2022年9月15日
    31400
  • 怎么用Python实现自动化处理每月考勤缺卡数据

    一、效果展示 1.实现效果 首先来看下实现效果。 大体实现步骤如下: 步骤1:在D盘中新建“每月缺卡数据处理“文件夹(已在代码中固定死了,必须建该文件夹)。 步骤2:把处理考勤缺失的exe文件和原始数据文件放到step1新建的文件夹中。 步骤3:点击exe文件,会自动出来csv结果文件,具体格式如下…

    2022年9月21日
    28500
  • Python如何安装及建立虚拟环境

    一、python安装 python安装以Python3.7.9版本为例,其他版本安装步骤一致。 Python官网 二、建立虚拟环境 win+r,打开dos窗口 查看python是否安装成功 安装virtualenv,安装命令: pip install virtualenv -i https://py…

    2022年9月6日
    32400
  • SQL注入中宽字节注入是什么

    宽字节注入:是属于SQL注入的一种绕过方式 一、宽字节概念: 1、单字节字符集:所有的字符都使用一个字节来表示,比如 ASCII 编码(0-127) 2、多字节字符集:在多字节字符集中,一部分字节用多个字节来表示,另一部分(可能没有)用单个字节来表示。 3、UTF-8 编码: 是一种编码的编码方式(…

    2022年9月6日
    27400
  • mysql列转行函数指的是什么

    在mysql中,列转行函数是“group_concat()”函数;该函数用于将非空列值按照分组条件进行合并并最终返回,如果其中有空值则返回的结果是空,语法为“select group_concat(name separator ‘;’)列名 from 表名;”。 本教程操作环…

    2022年9月16日
    1.6K00
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部