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

相关推荐

  • mysql分页查询如何优化

    分页查询的优化方式:1、子查询优化,可通过把分页的SQL语句改写成子查询的方法获得性能上的提升。2、id限定优化,可以根据查询的页数和查询的记录数计算出查询的id的范围,然后根据“id between and”语句来查询。3、基于索引再排序进行优化,通过索引去找相关的数据地址,避免全表扫描。4、延迟…

    2022年9月24日
    2.3K00
  • 如何进行AppLocker绕过分析

    前言 什么是applocker AppLocker即“应用程序控制策略”,是Windows 7系统中新增加的一项安全功能。在win7以上的系统中默认都集成了该功能,我们可以使用在services中启用Application Identity,然后在local security policy中找到Ap…

    2022年9月16日
    71000
  • 怎么使用Performance监控前端性能

    Performance.now Performance是一个做前端性能监控离不开的API,较好在页面完全加载完成之后再使用,因为很多值必须在页面完全加载之后才能得到。最简单的办法是在window.onload事件中读取各种数据。 performance.now()方法返回一个精确到毫秒的 DOMHi…

    2022年8月29日
    1.1K00
  • “开会”的正确打开方式:盘点那些没必要开和应该开的会

    先想象一个场景:每天在你忙的焦头烂额之时,你的钉钉/企业微信/Worktile等办公协作软件突然弹出一个开会通知……你的名列前茅反应肯定是:“怎么又要开会啊?”因为一个会议,大半天的工作时间又没了。 不知道从何时起,频繁且冗长的会议占据了我们的大多数工作时间,严重降低了工作效…

    2022年3月20日
    88100
  • 电脑驱动位置如何查看

    电脑驱动查看方法: 1、首先我们点击任务栏中的搜索按钮。 2、打开搜索栏后,在其中搜索并打开“设备管理器” 3、双击打开想要查看的电脑驱动程序。 4、然后点击上方的“驱动程序”选项卡。 5、点击“驱动程序详细信息” 6、然后在图示位置就可以看到电脑驱动信息了。 7、如果你觉得操作比较麻烦可以尝试使用…

    2022年9月21日
    2.0K00
  • 如何进行Web权限维持分析

    前言 权限维持,在红蓝对抗中,我觉得其意义在于两点:一是防止已获取的权限被蓝队破坏;二是防止其他红队获取到相同的权限(虽然有点缺德。。。)。 其他情况下的非法用途就不说了。 权限维持的原则我觉得就是不能影响原来业务的正常运行。(比如改后台密码导致管理员不能登录,修改文件夹读写权限导致正常的文件不能上…

    2022年9月24日
    55300
  • vlookup函数精确匹配怎么选择

    vlookup函数精确匹配是1还是0 答:vlookup函数精确匹配是0 1、0代表的是精确匹配,1代表的是模糊匹配。 2、此外,FALSE也可以代表精确匹配,true代表近似匹配。 3、使用精确匹配,就是必须要查找值必须完全匹配,才会导出结果。 4、而模糊匹配有类似值就会匹配到结果中。 5、我们可…

    2022年9月22日
    1.0K00
  • windows deepl如何卸载

    deepl卸载方法 1、点击控制面板。 2、点击“程序和功能” 3、右键想要卸载的软件,卸载maya的这里就右键maya。 4、点击卸载即可。 以上就是“windows deepl如何卸载”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如…

    2022年9月26日
    1.7K00
  • vlookup函数如何使用

    vlookup函数使用方法 vlookup 的作用: vlookup 用于查找指定值所对应的另一个值。例如:查找某件产品的价格,某个同学的某科成绩等。 vlookup 函数表示: =vlookup(要查找的值,查找区域,返回值所在列号,精确匹配或近似匹配) 参数说明: 1、要查找的值:可以引用单元格…

    2022年9月21日
    73300
  • jquery如何监听select的改变

    监听步骤:1、利用change()给select元素绑定改变事件,并设置事件处理函数,语法“$(“select”).change(function() {…});”;2、在事件处理函数中,设置事件触发后需要执行的代码,语法“alert(“选项已被改变&…

    2022年9月13日
    4.0K00
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

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

分享本页
返回顶部