Java动态代理简易说明

简介: Java动态代理简易说明

先看一下java.lang.reflect.Proxy的实例化方法声明

/**
     ...
     * @param   loader the class loader to define the proxy class
     * @param   interfaces the list of interfaces for the proxy class
     *          to implement
     * @param   h the invocation handler to dispatch method invocations to
     * @return  a proxy instance with the specified invocation handler of a
     *          proxy class that is defined by the specified class loader
     *          and that implements the specified interfaces
  ...
*/
    @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

显然,实例化一个Proxy对象需要传三个参数:

ClassLoader 类加载器
Class<?>[] 类型数组,这里只能传接口数组,决定了生成的代理对象可以转换成的类型
InvocationHandler 实际代理处理类

然后我们再看InvocationHandler的接口方法

/**
     ...
     * @param   proxy the proxy instance that the method was invoked on
     *
     * @param   method the {@code Method} instance corresponding to
     * the interface method invoked on the proxy instance.  The declaring
     * class of the {@code Method} object will be the interface that
     * the method was declared in, which may be a superinterface of the
     * proxy interface that the proxy class inherits the method through.
     ...
     */
public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;

显然,invoke方法有三个参数:

Object proxy 代理实例,这里实际上是代理实例把自己作为参数传递了,只能用作类型判断,否则会产生循环嵌套调用,导致栈溢出
Method method 方法实例,这里需要了解反射的知识,其是proxy调用的任何方法的方法实例
Object[] args 这个是proxy调用方法时传递的实例

由此看出,仅仅实现了InvocationHandler的类没有任何用处,因为Method的调用需要一个实现该方法的类实例

/**
     ...
     * @param obj  the object the underlying method is invoked from
     * @param args the arguments used for the method call
     * @return the result of dispatching the method represented by
     * this object on {@code obj} with parameters
     ...
     */
    @CallerSensitive
    public Object invoke(Object obj, Object... args)

好了,方法基本说完了,下面是重点中的重点:

代理实例方法(任何方法)的调用,都是通过InvocationinHandler的Invoke()调用的,InvocationinHandler处理的粒度是方法。

下面是例子

首先是要被代理的接口和接口的实现

public interface IMethodInvoke {
   
    public void psvm();
}
public class MethodInvoke implements IMethodInvoke{
   
    public MethodInvoke() {
   
    }
    public void psvm() {
   
        System.out.println("psvm方法调用!");
    }

}

然后是InvocationinHandler

public class MessageHandler implements InvocationHandler{
   
    private Object cli;
    public MessageHandler(Object cli) {
   
        this.cli=cli;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
        System.out.println("发送信息");
        return  method.invoke(cli, args);
    }

}

最后是Main

public static void main(String[] args) {
   
    IMethodInvoke imi = new MethodInvoke();
    InvocationHandler ivh = new MessageHandler(imi);
    IMethodInvoke proxy = (IMethodInvoke)Proxy.newProxyInstance(imi.getClass().getClassLoader(), imi.getClass().getInterfaces(), ivh);
    User user = new User();
    Class[] users = {
   User.class}; 
    User userProxy = (User)Proxy.newProxyInstance(imi.getClass().getClassLoader(), users, ivh);
    proxy.psvm();//作为ivh的Invoke方法的参数中的Method,和Object[],Proxy则是代理实例本身
    System.out.println("Out"+proxy.toString());
}
目录
相关文章
|
24天前
|
设计模式 Java API
[Java]静态代理与动态代理(基于JDK1.8)
本文介绍了代理模式及其分类,包括静态代理和动态代理。静态代理分为面向接口和面向继承两种形式,分别通过手动创建代理类实现;动态代理则利用反射技术,在运行时动态创建代理对象,分为JDK动态代理和Cglib动态代理。文中通过具体代码示例详细讲解了各种代理模式的实现方式和应用场景。
20 0
[Java]静态代理与动态代理(基于JDK1.8)
|
1月前
|
Java
深入理解Java动态代理
深入理解Java动态代理
19 1
|
28天前
|
Java
Java代码解释静态代理和动态代理的区别
### 静态代理与动态代理简介 **静态代理**:代理类在编译时已确定,目标对象和代理对象都实现同一接口。代理类包含对目标对象的引用,并在调用方法时添加额外操作。 **动态代理**:利用Java反射机制在运行时生成代理类,更加灵活。通过`Proxy`类和`InvocationHandler`接口实现,无需提前知道接口的具体实现细节。 示例代码展示了两种代理方式的实现,静态代理需要手动创建代理对象,而动态代理通过反射机制自动创建。
|
1月前
|
设计模式 缓存 Java
从源码学习Java动态代理|8月更文挑战
从源码学习Java动态代理|8月更文挑战
|
4月前
|
缓存 Java 测试技术
day27:Java零基础 - 动态代理
【7月更文挑战第27天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
42 2
day27:Java零基础 - 动态代理
|
3月前
|
开发者 C# 容器
【独家揭秘】当WPF邂逅DirectX:看这两个技术如何联手打造令人惊艳的高性能图形渲染体验,从环境搭建到代码实践,一步步教你成为图形编程高手
【8月更文挑战第31天】本文通过代码示例详细介绍了如何在WPF应用中集成DirectX以实现高性能图形渲染。首先创建WPF项目并使用SharpDX作为桥梁,然后在XAML中定义承载DirectX内容的容器。接着,通过C#代码初始化DirectX环境,设置渲染逻辑,并在WPF窗口中绘制图形。此方法适用于从简单2D到复杂3D场景的各种图形处理需求,为WPF开发者提供了高性能图形渲染的技术支持和实践指导。
222 0
|
3月前
|
设计模式 Java C++
揭秘!JDK动态代理VS CGLIB:一场关于Java代理界的‘宫心计’,你站哪队?
【8月更文挑战第24天】Java 动态代理是一种设计模式,允许在不改动原类的基础上通过代理类扩展功能。主要实现方式包括 JDK 动态代理和 CGLIB。前者基于接口,利用反射机制在运行时创建代理类;后者采用继承方式并通过字节码技术生成子类实现类的代理。两者在实现机制、性能及适用场景上有明显差异。JDK 动态代理适用于有接口的场景,而 CGLIB 更适合代理未实现接口的类,尽管性能更优但存在一些限制。开发者可根据需求选择合适的代理方式。
180 0
|
4月前
|
开发框架 Java Android开发
Java中的类反射与动态代理详解
Java中的类反射与动态代理详解
|
4月前
|
Java 数据安全/隐私保护
Java中的动态代理机制详解
Java中的动态代理机制详解
|
4月前
|
Java
Java中的反射与动态代理机制详解
Java中的反射与动态代理机制详解