亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

Java使用Porxy和InvocationHandler實現動態代理

標簽:
Java

代理模式:通过代理间接的调用被代理对象的方法,结构如下:

https://img1.sycdn.imooc.com//5be948e300014a7410000658.jpg

image.png

Java的反射包提供了一个Porxy类和InvokationHandler接口。它们结合在一起后可以创建动态代理类。Porxy类基于传递的参数创建动态代理类。InvokationHandler则用于激发动态代理类的方法。这个过程是在程序执行过程中动态生成与处理的,所以叫动态代理。分析一下

Porxy类

Porxy类提供了一个静态方法创建动态代理类。

public static Object newProxyInstance(ClassLoader loader,
    Class<?>[] interfaces,
    InvocationHandler h)
throws IllegalArgumentException

1、ClassLoader:ClassLoader会定义动态代理类,ClassLoader可以通过类或者接口获得,如果我们想通过接口获得,调用方法如下。

    Task.class.getClassLoader()

如果通过类来获得,加入我们有一个类TaskImpl实现了Task接口,我们有个TaskImpl的对象ob,然后ClassLoader获取方法如下

    ob.getClassLoader()

2、 Class<?>[] interfaces:动态代理类需要实现的接口
3、InvocationHandler:传递一个实现了InvokationHandler接口的类的实例

InvokationHandler

InvokationHandler是Java 反射包里面的一个接口。InvokationHandler通过用户类来实现,来激发一个动态代理类的方法。它只有一个方法:

public Object invoke(Object proxy, Method method, Object[] args)    throws Throwable;

1、Object:实现方法的代理对象
2、Method:代理实例激发的方法,Porxy参数中的接口方法
3、Object[]:传递给方法的一系列参数

实现

1、我们提供一个接口

package me.aihe;
 
public interface Task {
    void setData(String data);
    int getCalData(int x);
}
 

2、实现这个接口

package me.aihe;
 
public class TaskImpl implements Task {
    @Override
    public void setData(String data) {
        System.out.println(data+ " Data is saved");
    }
 
    @Override
    public int getCalData(int x) {
        return x * 10;
    }
}
 

3、定义自己的InvokationHandler类,并且实现InvokationHandler接口的Invoke方法

package me.aihe;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 
public class MyInvokationHandler implements InvocationHandler {
 
    private Object obj;
    public MyInvokationHandler(Object object){
        this.obj = object;
    }
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result;
        if(method.getName().contains("get")){
            System.out.println("...get Method Executing...");
        }else{
            System.out.println("...set Method Executing...");
        }
        result = method.invoke(obj, args);
        return result;
    }
}
 

4、创建一个工厂类获取动态代理类:

package me.aihe;
 
import java.lang.reflect.Proxy;
 
public class ProxyFactory {
    public static Object newInstance(Object ob) {
        return Proxy.newProxyInstance(ob.getClass().getClassLoader(),
                new Class<?>[] { Task.class }, new MyInvokationHandler(ob));
    }
}
 

5、提供我们的测试类

package me.aihe;
 
public class Test {
 
    public static void main(String[] args) {
        Task task = (Task)ProxyFactory.newInstance(new TaskImpl());
        task.setData("Test");
        System.out.println("============");
        System.out.println(task.getCalData(5));
    }
}
 

看到程序的输出结果:

...set Method Executing...
Test Data is saved
============
...get Method Executing...
50

总结

动态代理的实现流程:
1、创建一个接口
2、提供一个实现这个接口的类
3、创建一个实现了InvokationHandler接口的类,实现Invoke方法。
传递参数:实现接口的类
4、可选:创建一个代理工厂。
返回值传递参数:ClassLoader,实现的接口,实现接口的类

参考:


點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
JAVA開發工程師
手記
粉絲
1.1萬
獲贊與收藏
1545

關注作者,訂閱最新文章

閱讀免費教程

  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消