java中的动态代理(二)

上一节我介绍了什么是静态代理。在静态代理中的代理对象是直接定义在代码中的,这样会导致代码不能复用并且工作量也会成倍的增加所以在日常的开发中我们更多使用的是动态代理模式。在动态代理中,代理类在是程序运行中动态生成的,在java中一般有两种方式来实现动态代理模式,它们分别是javaSDK动态代理和第三方类库cglib动态代理。

今天我介绍的是java SDK动态代理。首先我们先来看一下如何使用java SDK实现动态代理模式:

public class JavaSDKProxyTest {

    static interface BaseService {
        void say();
    }

    static class RealService implements BaseService {
        @Override
        public void say() {
            System.out.println("i am realService!");
        }
    }

    static class ProxyInvocationHandler implements InvocationHandler{
        private Object service;

        public ProxyInvocationHandler(Object service){
            this.service = service;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("say before");
            Object object = method.invoke(this.service, args);
            System.out.println("say after");
            return object;
        }
    }

    public static void main(String[] args) {
        BaseService realService = new RealService();
        BaseService proxyService = (BaseService) Proxy.newProxyInstance(BaseService.class.getClassLoader(),
                new Class<?>[]{BaseService.class},new ProxyInvocationHandler(realService));
        proxyService.say();

    }
}

感觉代码看起来更加的复杂了,没事其实还是比较的好理解的。BaseService和RealService是公共的接口和真正的对象,它们两个的定义方式没有变化。但是代理对象的创建方式变了,使用的是Proxy这个类里面的一个静态方法newProxyInstance。这个方法需要传三个参数,第一个参数是当前类的类加载器,这里只需要保证和公共接口使用的是同一个类加载器即可,关于ClassLoader我会在下面的文章中单独介绍。第二个参数是一个字节码的对象数组表示的是要实现的接口列表,这里需要注意的是数组中元素的类型只能是接口,不能是普通的类,在该例中只有一个公共的接口就是BaseService。第三个参数是InvocationHandler,它是一个接口只定义了一个方法就是invoke,对代理接口中的所有的方法的调用都会转给该方法。方法newProxyInstance返回的是Object类型但是可以强制转换为字节码数组中的任意接口类型,但是需要注意的是不可以强制转换为接口对应的实现类的类型。

ProxyInvocationHandler实现了InvocationHandler接口,这个接口中的invoke方法中有三个参数,其中proxy表示的代理对象,method表示的是正在被调用的方法,args表示正在被调用的方法的参数。所以当我们需要执行被代理对象的方法时可以利用反射来调用:Object result = method.invoke(realObject,args),这里需要注意的是不要把proxy当成被代理的对象传到invoke方法中,如果把proxy传到invok方法中会导致死循环。

与静态代理相比动态代理在实现上更加的复杂但是设计的思想是一样的。今天我介绍的java SDK的动态代理的局限在于它只能为接口创建代理,返回的代理对象也只能强转成接口类型,如果一个类没有实现接口就不适用了。

原文地址:https://www.cnblogs.com/suyang-java/p/10925545.html

时间: 2024-11-05 20:29:16

java中的动态代理(二)的相关文章

十分钟理解Java中的动态代理

十分钟帮助大家理解Java中的动态代理,什么是动态代理?感兴趣的小伙伴们可以参考一下 若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的. 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类. 一.概述1. 什么是代理我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家"委托"代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道背后的厂家究竟是谁,也就是说,"委托

java中的动态代理机制

在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的.下面通过代码来学习java中的动态代理技术. 首先定义一个接口: package com.aop.spring; /** * Created by xinfengyao on 16-2-29. */ public interface Perform { public void play(); } 实

使用Java中的动态代理实现数据库连接池

2002 年 12 月 05 日 作者通过使用JAVA中的动态代理实现数据库连接池,使使用者可以以普通的jdbc连接的使用习惯来使用连接池. 数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的连接数据库对服务性能来讲是一个瓶颈,使用缓冲池技术可以来消除这个瓶颈.我们可以在 互联网上找到很多关于数据库连接池的源程序,但是都发现这样一个共同的问题:这些连接池的实现方法都不同程度地增加了与使用者之间的耦合度.很多的连接池 都要求用户通过其规定的方法获取数据库的连接,这一点我们可以理解,毕竟目前

Java 代理模式(二) Java中的动态代理

动态代理类 Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类: 1.Interface InvocationHandler 该接口中仅定义了一个方法: Object invoke(Object proxy, Method method, Object[] args) 在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组(无参时设置为null). 这个抽象方法在代理类中动态实现. 2

java中的动态代理

一.类中实现了接口,使用java.lang.reflect.Proxy类,创建一个代理工厂,可以动态代理类中方法. 说明:被代理的类需要有实现的接口. 例子: 1 实体类代码 实体类代码 public class UserDao implements IUserDao{ public UserDao() { // TODO Auto-generated constructor stub } public void saveUser() { System.out.println("保存用户成功,s

Java中的动态代理以及Proxy类的偷瞄

动态代理机制 所谓动态代理,即通过代理类Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. Java动态代理类位于Java.lang.reflect包下,主要涉及到两个类. (1)接口InvocationHandler:该接口中仅定义了一个方法. Object invoke(Object obj, Method method, Object[] args); 在实际使用时,第一个参数obj一般指代理类,method是被代理的方法,args为该方法

Java中的动态代理及反射机制

面向对象的基本原则封装.继承.多态,在java中多态机制,表现为变量多态,方法多态,这都是指的是因对象所属的类不同,而调用不同的类方法:对于对象的方法,还有函数重载,java中的函数的签名是由函数名+参数方法来定的,不能仅由返回值不同来定. 反射Reflect 运行时获取类的类型,域,方法等各种属性. Class是一个类,其实例对应其他不同分 (CalculatorImpl)Class.forName("CalculatorImpl").newInstance(); newInstan

java中的动态代理Proxy

动态代理是java语言的一个神奇的地方,不是很好理解,下面来看看关键的地方. InvocationHandler 是一个接口,官方文档解释说,每个代理的实例都有一个与之关联的 InvocationHandler 实现类,如果代理的方法被调用,那么代理便会通知和转发给内部的 InvocationHandler 实现类,由它决定处理. public interface InvocationHandler { public Object invoke(Object proxy, Method meth

java中的动态代理(一)

今天我们来学习java中的另一个重要的特性叫做动态代理.所谓动态代理是可以在java运行过程中动态的创建一个类去实现一个或多个接口,可以在不修改原有类代码的基础上动态的添加功能和方法.正是因为这个特性使动态代理被java的许多框架中被广泛的使用. 在介绍动态代理之前我需要先介绍一下什么是静态代理.在设计模式那一章我曾经介绍过一种设计模式叫做代理模式.在代理模式中有一个公共的接口,代理对象和实际的对象都需要去实现这个接口.在代理对象中有一个成员属性变量指向实际对象并在代理对象的构造函数中初始化,在