动态代理Java实现

思考:在IBuyWatermelon添加一个方法selectWatermelon()

静态代理中需要在RealSubject中实现该方法,而且Proxy也要实现该方法调用RealSubject中的实现,如果再增加10个方法还是得这样操作,导致大量的代码重复。

现在来看动态代理(顾名思义,是在运行时才形成的代理对象,不像静态代理在编译时就载入代理对象)。

生成动态代理的方法有很多: JDK中自带的动态代理java.lang.reflect.*, CGlib等

下面的例子是JDK中自带的动态代理java.lang.reflect.*

IBuyWatermelon():接口

package com.maggie.dynamicproxy;

public interface IBuyWatermelon {
    //代理事件
    public abstract String buyWatermelon();

    public abstract void selectWatermelon();
}

BuyWatermelonImpl:实现类

package com.maggie.dynamicproxy;

//可理解成被代理者
public class BuyWatermelonImpl implements IBuyWatermelon {

    private Supermarket supermaket;

    public BuyWatermelonImpl(Supermarket supermaket) {
        super();
        this.supermaket = supermaket;
    }

    @Override
    public String buyWatermelon() {
        System.out.println("在"+supermaket.getName()+" 买西瓜");
        return "watermelon";
    }

    @Override
    public void selectWatermelon() {
        System.out.println("选择无籽西瓜");
    }

}

ProxyFactory:代理对象类(核心代码)

package com.maggie.dynamicproxy;

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

public class ProxyFactory {
     //维护一个目标对象
    private Object target;
    public ProxyFactory(Object target){
        this.target=target;
    }

   //给目标对象生成代理对象
    public Object getProxyInstance(){
        //动态代理的核心,涉及到反射
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            //执行目标对象方法
                            Object returnValue = method.invoke(target, args);
                            return returnValue;
                    }
                }
        );
    }

}

客户端调用

package com.maggie.dynamicproxy;

public class Main {
    public static void main(String[] args) {
        Supermarket zhaoLiu = new Supermarket();
        zhaoLiu.setName("赵六超市");
        IBuyWatermelon target  = new BuyWatermelonImpl(zhaoLiu);//被代理的对象

        //创建代理对象
        IBuyWatermelon hourskeeper = (IBuyWatermelon) new ProxyFactory(target).getProxyInstance();

        hourskeeper.buyWatermelon();
        hourskeeper.selectWatermelon();

    }
}

输出

在赵六超市 买西瓜
选择无籽西瓜

现在就算IBuyWatermelon的方法再怎么增加,也只需要在BuyWatermelonImpl实现,就可以在客户端调用,不会出现大量的重复代码。

从静态代理到动态代理都围绕着卖瓜事件,为了前后方便比较,但是动态代理并没完,里面的源码机制才是核心关键

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)这个方法是整个动态代理实现的关键

时间: 2024-11-05 11:32:21

动态代理Java实现的相关文章

java 动态代理示例,带主要注释

Java proxy是基于反射,仅仅支持基于接口的动态代理. java 动态代理是一切架构的基础,必须了解. 废话少说,先上代码获得感性认识. 示例代码有主要注释. 接口: public interface Subject { String hello(String name); void say();} 接口实现: public class ImpSubject implements Subject { @Override public String hello(String name){ r

Java基础:静态代理和动态代理

转载请注明出处:jiq?钦's technical Blog 一.静态代理: 假设原来有一个实现了指定接口/抽象类的子类: class RealSubject implements Subject{ public void request(){ System.out.print("real request handling\n"); } } 现在有两种情况会发生: 1新的代码需要调用Subject接口,但是需要给每个接口加入新代码(比如日志记录.权限控制等): 2旧的代码已经使用了Su

java 静态代理 JDK动态代理 Cglib动态代理

下面以一个简单的银行账户为例讲述讲述动态代理. 设计一个银行账户类,包含用户的账户余额,实现查询和更新余额功能 这个系统用了一段时间,有客户要求对账说账户余额给弄错了?因为上面没有存取款记录,最后银行不认账,客户收到了损失.银行为了避免这种现象再次发生,决定对这个系统进行修改,但是因为bankAccount太过复杂,希望在不修改bankAccount的情况下,增加日志功能. 静态代理 使用静态代理解决上面的问题. 银行要求所有模块都需要添加日志功能,这对苦逼的程序员来说真的是一个不小的工作量啊,

java --- 设计模式 --- 动态代理

Java设计模式——动态代理 java提供了动态代理的对象,本文主要探究它的实现, 动态代理是AOP(面向切面编程, Aspect Oriented Programming)的基础实现方式, 动态代理使代码的重复更少,更便与维护 本文参考了满一行老师和马士兵老师的视频,在此表示Thanks. 假设小张通过QQ和一个网名为如花的妹纸聊天, 而在QQ的另一端,这个网名为如花的妹纸的name是小丽 但是,正在聊天的时候小丽生病了不想打字,小丽就找她的男朋友帮忙回应 小丽的男朋友在如花的QQ账号上与小张

java高级----&gt;Java动态代理的原理

Java动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.下面我们开始动态代理的学习. 目录导航   动态代理的简要说明 简单的Java代理 Java的动态代理 Java动态代理的原理 友情链接 动态代理的简要说明 在java的动态代理机制中,有两个重要的类或接口,一个是 In

Java的反射机制和动态代理

介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大的功能,可以原生实现AOP中 的方法拦截功能.正如英文单词reflection的含义一样,使用反射API的时候就好像在看一个Java类在水中的倒影一样.知道了Java类的内部 结构之后,就可以与它进行交互,包括创建新的对象和调用对象中的方法等.这种交互方式与直接在源代码中使用的效果是相同的,但是又额外提供了运行时

Java类型信息与应用--动态代理

Java类型信息与应用--动态代理 本文结构 一.前言 二.为什么需要RTTI 三.RTTI在java中的工作原理 四.类型转化前先做检测 五.动态代理 六.动态代理的不足 一.前言 运行时信息使你可以在程序运行时发现和使用类型信息 Java在运行时识别对象和类的信息的方式: 1.一种是RTTI,它假定我们在编译时已经知道了所有的类型. 2.另一种是"反射"机制,它允许我们在运行时发现和使用类的信息. 这带来的好处是,你可以在程序运行时发现和使用类型信息 二.为什么需要RTTI 以多态

代理模式和java动态代理

代理模式的作用及使用场景 使用代理模式的根本目的在于:如何在不直接操作对象的情况下,对此对象进行访问? 常用的场合包括:1)延迟加载:2)在调用实际对象的方法前后加入某些业务逻辑(作用有点像spring的AOP) 类结构: JAVA动态代理 JAVA提供了动态代理类以供用户方便地实现代理模式 public interface Subject { public void doRequest(); } public class SubjectImpl implements Subject { pub

Java动态代理的实现机制

一.概述 代理是一种设计模式,其目的是为某对象提供一个代理以控制对该对象的访问,代理类负责为被代理类处理消息,过滤消息以及后续处理.为了保持行为的一致性,代理类和被代理类通常会实现相同的接口. 按照代理的创建时期,代理可以分为两种: 静态代理:由程序员创建代理类,也就是说在程序运行期代理类的.class文件就已经存在. 动态代理:在程序运行时运行反射机制动态创建生成代理类 在介绍动态代理之前我们先简单介绍一下静态代理. 二.静态代理 上面说过,代理类和被代理类一般都要实现相同的接口,我们定义一个