首页 > 编程语言 >java动态代理模式

java动态代理模式

时间:2024-04-19 09:44:07浏览次数:24  
标签:调用 Java 代理 接口 InvocationHandler java 动态 public

  • Java动态代理模式是Java编程语言中的一种设计模式,它提供了一种在运行时动态创建代理对象的方式。这个模式主要用于实现AOP(面向切面编程)的概念,允许开发者在不修改原有业务逻辑代码的情况下,增加额外的功能,如日志记录、事务管理、权限验证等。
    在Java中,动态代理模式主要依赖于java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。Proxy类提供了创建代理对象的方法,而InvocationHandler接口定义了代理对象在调用方法时需要实现的接口。
  • 动态代理模式的实现步骤如下:
  1. 定义一个接口,该接口定义了需要被代理的方法,比如:
public interface GreetingService {
    void greet(String name);
}
  1. 实现该接口的具体业务逻辑类。
public class SimpleGreetingService implements GreetingService{
    @Override
    public void greet(String name) {
        System.out.println("Hello,"+name+"!");
    }
}
  1. 创建一个实现了InvocationHandler接口的类,该类负责处理代理对象的方法调用。在这个类中,可以添加额外的功能,如日志记录、事务管理等。
public class LoggingInvocationhandler implements InvocationHandler {

    private final Object target;


    public LoggingInvocationhandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //在方法调用前记录日志
        System.out.println("Method: "+ method.getName()+ " is called with arguments: "+ Arrays.toString(args));

        //调用目标对象的方法
        Object result = method.invoke(target, args);
        //在方法调用后记录日志
        System.out.println("Method "+ method.getName()+" is executed");
        return result;
    }
}
  1. 使用Proxy类的静态方法newProxyInstance()创建代理对象。该方法需要三个参数:被代理类的类加载器、被代理类实现的接口数组、实现了InvocationHandler接口的实例。通过代理对象调用方法时,会调用InvocationHandler接口中的invoke()方法。在该方法中,可以添加额外的功能,然后调用被代理对象的方法。
import java.lang.reflect.Proxy;

public class DynamicProxyExample {
    public static void main(String[] args) {
        //创建目标对象
        SimpleGreetingService greetingService = new SimpleGreetingService();
        //创建InvocationHandler对象
        LoggingInvocationhandler handler = new LoggingInvocationhandler(greetingService);

        //创建代理对象
        GreetingService proxy = (GreetingService) Proxy.newProxyInstance(
                handler.getClass().getClassLoader(),
                greetingService.getClass().getInterfaces(),
                handler);

        //调用代理对象的方法,实际上会调用InvocationHandler的invoke方法
        proxy.greet("World");
    }
}

动态代理模式的优点是可以在运行时动态创建代理对象,而不需要提前编写代理类的代码。这使得开发者可以更加灵活地实现AOP的概念,提高了代码的可维护性和可扩展性。

  • 在Java中,动态代理模式是基于接口的。这意味着你不能直接为一个没有接口的类创建动态代理。动态代理是通过在运行时生成一个新的类来实现的,这个新类实现了你指定的接口,并且将所有方法调用委托给一个InvocationHandler实例。
    具体来说,当你使用Proxy.newProxyInstance()方法创建一个代理对象时,你需要提供一个接口数组作为参数之一。这个数组中的接口定义了代理对象需要实现的方法。因此,如果没有接口,动态代理就无法工作。
    如果你有一个没有实现任何接口的类,并且想要为它创建代理,那么你不能使用Java标准库中的动态代理模式。在这种情况下,你可能需要使用其他技术或库,如CGLIB。CGLIB是一个强大的高性能的代码生成库,它可以在运行时扩展Java类与实现Java接口。它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的拦截。
    总结一下,"动态代理模式只能用于接口,不能用于类"这句话的意思是:在Java中,你不能直接为没有实现接口的类创建动态代理。如果你需要为一个类创建代理,你可能需要使用其他技术或库,如CGLIB。

标签:调用,Java,代理,接口,InvocationHandler,java,动态,public
From: https://www.cnblogs.com/DuWenjie/p/18145138

相关文章

  • JavaScripts浮点数计算问题
    JS数学运算精度问题最近项目上JS做加减乘除这类的运算出现了精度不匹配的问题:例如:0.1+0.2->0.300000000000000040.3-0.2->0.099999999999999980.3*2->0.60.3*0.20.060.3/3->0.09999999999999999Mathjs这个JS库可以解决这类问题:官网链接以下是详细的步骤:终端执......
  • 3.Java基础学习
    Java基础注释单行注释多行注释文档注释publicclassHelloworld{publicstaticvoidmain(String[]args){//单行注释////输出一个HelloworldSystem.out.println("Helloworld");/*多行注释多行注释......
  • Java题目集1-3总结
    (1)前言:第一次大作业的知识点包括类与对象正则表达式以及数组对象和不同类之间的关系;题量较小,难度不大,关键是理清question,test-paper,answer-paper之间的关系。第二次大作业的知识点增加了List,ArrayList,HashMap,三种变长数组的使用,增加了正则表达式的难度,题量增加,难度上升,试卷中的......
  • Trino418版本动态加载catalog不需要重启集群修改思路及实现2
       原来没事的时候改了一个这样的功能,当时也没有仔细研究,后来也没继续弄。详细可以参考 https://www.cnblogs.com/liuzx8888/p/17635913.html当时有1个问题:新增数据源需要每一个节点都去调取API注册,这样非常麻烦,最近闲下来又研究了一下,在原先的基础上做了一些改造。具体流......
  • java-collections-map t
    MapMap常用子类HashMap:HashMap是最常用的Map实现之一,它基于哈希表实现,提供了O(1)时间复杂度的插入、删除和查找操作。Hashtable:Hashtable是较早期的Java集合类,它是线程安全的,但性能通常比HashMap差,因为它的方法是同步的。TreeMap:TreeMap是基于红黑树实现的有序Ma......
  • 洛谷题单指南-动态规划1-P1115 最大子段和
    原题链接:https://www.luogu.com.cn/problem/P1115题意解读:计算最大字段和,典型dp问题。解题思路:设a[]表示所有整数,f[i]表示以第i个数结束的最大字段和当f[i-1]>=0时,f[i]=f[i-1]+a[i]否则,f[i]=a[i]因此,递归式为f[i]=max(a[i],f[i-1]+a[i])注意整数可能为负,ans初始......
  • Pyecharts制作动态GDP柱状图
    学习使用pyecharts制作动态柱状图使用csv模块进行csv数据文件处理importcsvfrompyecharts.chartsimportBar,Timelinefrompyecharts.optionsimport*frompyecharts.globalsimportThemeTypedefdealCSVFile():"""读取处理csv数据文件:retu......
  • java 代码编译检查工具
    <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version><configuration><encoding&......
  • 洛谷题单指南-动态规划1-P1434 [SHOI2002] 滑雪
    原题链接:https://www.luogu.com.cn/problem/P1434题意解读:计算能滑行的最长距离。解题思路:设dp(i,j)表示从i,j可以滑行的最大距离对于4个方向i,j可以到达的点,ni,nj,如果可以滑过去(ni,ni所在点高度更低)则dp(i,j)=max(dp(i,j),1+dp(ni,nj))为了便于搜索4个方向的各条路径,......
  • CXF WebService wsdl2java
    下载apache-cxf-3.3.1并解压到bin目录下,输入生成命令wsdl2java-encodingutf-8-dD:\Software\Webservice\wshttp://XXX.XXX.XXX.XXX:XXX/WSInterface.asmx?wsdl把生成的文件,复制到项目中,进行后续编码......