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()

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java动态代理之拦截器的应用

    由于动态代理一般都比较难理解,程序设计者会设计一个拦截器接口供开发者使用,开发者只要知道拦截器接口的方法.含义和作用即可,无须知道动态代理是怎么实现的.用JDK动态代理来实现一个拦截器的逻辑,为此先定义拦截器接口Interceptor,如下所示: /** * @Auther: haozz * @Date: 2018/5/27 22:15 * @Description:拦截器接口 **/ public interface Interceptor { boolean before(Object pr

  • Java中过滤器 (Filter) 和 拦截器 (Interceptor)的使用

    1.过滤器 (Filter) 过滤器的配置比较简单,直接实现Filter 接口即可,也可以通过@WebFilter注解实现对特定URL拦截,看到Filter 接口中定义了三个方法. init() :该方法在容器启动初始化过滤器时被调用,它在 Filter 的整个生命周期只会被调用一次.注意:这个方法必须执行成功,否则过滤器会不起作用. doFilter() :容器中的每一次请求都会调用该方法, FilterChain 用来调用下一个过滤器 Filter. destroy(): 当容器销毁 过滤器

  • Spring AOP拦截-三种方式实现自动代理详解

    这里的自动代理,我讲的是自动代理bean对象,其实就是在xml中让我们不用配置代理工厂,也就是不用配置class为org.springframework.aop.framework.ProxyFactoryBean的bean. 总结了一下自己目前所学的知识. 发现有三种方式实现自动代理 用Spring一个自动代理类DefaultAdvisorAutoProxyCreator: <bean class="org.springframework.aop.framework.autoproxy.

  • Java中的拦截器、过滤器、监听器用法详解

    本文实例讲述了Java中的拦截器.过滤器.监听器用法.分享给大家供大家参考,具体如下: 一.拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方 法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作. 1.Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,

  • Java web拦截器inteceptor原理及应用详解

    这篇文章主要介绍了java web拦截器inteceptor原理及应用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.简介 java里的拦截器提供的是非系统级别的拦截,也就是说,就覆盖面来说,拦截器不如过滤器强大,但是更有针对性. Java中的拦截器是基于Java反射机制实现的,更准确的划分,应该是基于JDK实现的动态代理.它依赖于具体的接口,在运行期间动态生成字节码. 拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发

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

    一.代理 在使用动态代理实现拦截器之前我们先简单了解一下什么Java的代理. 代理,顾名思义,就是不直接操作被代理(下面都用目标对象称呼,听起来舒服一些)对象,而是通过一个代理对象去间接的使用目标对象中的方法.代理分为两种模式,一种是静态代理,一种是动态代理.接下来先写一个静态代理的例子. 无论是静态代理还是动态代理,目标对象(target)都要实现一个接口(interface),注意,如果使用cglib提供的代理,则不必实现接口,而是通过子类去实现,暂不讨论该种方式. (1)先定义一个接口 p

  • java实现动态代理方法浅析

    一些Java项目中在mybatis与spring整合中有MapperScannerConfigurer的使用,该类通过反向代理自动生成基于接口的动态代理类. 有鉴于此,本文浅析了java的动态代理. 本文使用动态代理模拟处理事务的拦截器. 接口: public interface UserService { public void addUser(); public void removeUser(); public void searchUser(); } 实现类: public class

  • Java使用反射和动态代理实现一个View注解绑定库

    目录 支持的功能 代码 注解类 实现类 使用 使用反射结合动态代理实现一个View注解绑定库,支持View和事件绑定,代码简洁,使用简单,扩展性强. 支持的功能 @ContentView 绑定layout 替代setContentView() @BindView 绑定View 替代findViewById() @OnClick 绑定点击事件 替代setOnClickListener() @OnLongClick 绑定长按事件 替代setOnLongClickListener() 代码 注解类 @

  • 详解java中动态代理实现机制

    代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. JAVA各种动态代理实现的比较 接口 interface AddInterface{ int add(int a, int b); } interface SubInterfa

  • 详解Java Cglib动态代理

    今天来介绍另一种更为强大的代理--Cglib动态代理. 什么是Cglib动态代理? 我们先回顾一下上一篇的jdk动态代理,jdk动态代理是通过接口来在运行时动态创建委托类的代理对象,但是跟静态代理一样有一个缺点,就是必须和委托类实现相同的接口,当接口数量增加时,便需要增加代理类的数量才能满足需求,而且如果委托类是别人写的,而且没有实现任何接口,那么jdk动态代理就有些力不从心了. 这时候Cglib动态代理就脱颖而出了,Cglib并不依赖接口,可以直接生成委托类的代理对象,而且可以代理委托类的任意

  • Java JDK动态代理(AOP)用法及实现原理详解

    Java-JDK动态代理(AOP)使用及实现原理分析 第一章:代理的介绍 介绍:我们需要掌握的程度 动态代理(理解) 基于反射机制 掌握的程度: 1.什么是动态代理? 2.动态代理能够做什么? 后面我们在用Spirng和Mybatis的时候,要理解怎么使用的. 1.什么是代理? 代理,在我们日常生活之中就有体现,代购,中介,换ip,商家等等. 比如有一家美国的大学,可以对全世界招生.留学中介(代理 ) 留学中介(代理):帮助这家美国的学校招生,中介是学校的代理中介是代替学校完成招生功能 代理特点

  • Java深入分析动态代理

    目录 代理模式 静态代理 动态代理 JDK动态代理 CGLIB动态代理 JDK代理与CGLIB代理的区别 "代理"这个词相信大家并不陌生,简单来说就是代替厂家来售卖商品,代理替代厂家售卖商品,顾客找代理购买商品.也就是说:1)顾客和厂家之间是不可见的,顾客不知道背后的厂家是谁.2)代理可以对顾客进行“定位”,更精确的售卖给需要的客户群体. 代理模式 代理模式:为其他对象提供一种代理以控制对这个对象的访问,也就是创建一个代理对象作为客户端和目标对象之间的中介,主要目的就是保护目标对象或增

  • Java JDK动态代理(AOP)的实现原理与使用详析

    本文主要给大家介绍了关于Java JDK动态代理(AOP)实现原理与使用的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 一.什么是代理? 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 代理模式UML图: 简单结构示意图: 为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别.通过代理类这中间一层,能有效控制对委托类对

  • Java CGLib动态代理机制(全面解析)

    一.首先说一下JDK中的动态代理: JDK中的动态代理是通过反射类Proxy以及InvocationHandler回调接口实现的 但是,JDK中所要进行动态代理的类必须要实现一个接口,也就是说只能对该类所实现接口中定义的方法进行代理,这在实际编程中具有一定的局限性,而且使用反射的效率也并不是很高. 二.使用CGLib实现: 使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高.唯一需要注意的

  • 详解java JDK 动态代理类分析(java.lang.reflect.Proxy)

    详解java JDK 动态代理类分析(java.lang.reflect.Proxy) /** * JDK 动态代理类分析(java.lang.reflect.Proxy使用) * * @author 张明学 * */ public class ProxyStudy { @SuppressWarnings("unchecked") public static void main(String[] args) throws Exception { // 动态代理类:通用指定类加载器,和接

随机推荐