`

Java中动态代理类

    博客分类:
  • Java
阅读更多
1. Java中动态代理模式

实现动态代理必须实现InvocationHandler接口,实现invoke()方法。
生成代理使用Proxy类(代理)的newProxyInstance()方法。


Subject.java

public interface Subject{
    public void request();
}


RealSubject.java

public class RealSubject implements Subject{
    public void request(){
        System.out.println("From real subject!");
    }
}


DynamicSubject.java

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
 * 该代理类的内部属性是Object类型,实际使用的时候通过该类的构造方法传递进来一个对象此外,该类还实现了invoke方法,该方法中的method.invoke其实就是调用被代理对象的将要执行的方法,方法参数是sub,表示该方法从属于sub,通过动态代理类,我们可以在执行真实对象的方法前后加入自己的一些额外方法。*/
public class DynamicSubject implements InvocationHandler{
    private Object sub;
    public DynamicSubject(Object obj){
        this.sub = obj;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
        System.out.println("before calling: " + method);
        method.invoke(sub, args);
        System.out.println(args == null);
        System.out.println("after calling: " + method);
        return null;
    }
}


Client.java

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client{
    public static void main(String[] args){
        RealSubject realSubject = new RealSubject();
        InvocationHandler handler = new DynamicSubject(realSubject);
        Class<?> classType = handler.getClass();
        // 下面的代码一次性生成代理
        Subject subject = (Subject) Proxy.newProxyInstance(classType
.getClassLoader(), realSubject.getClass().getInterfaces(),handler);
        subject.request();
        System.out.println(subject.getClass());
    }
}
运行结果:
before calling: public abstract void org09.Subject2.request()
From real subject2!
true
after calling: public abstract void org09.Subject2.request()
class $Proxy0


2. VectorProxy

VectorProxy.java

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Vector;
public class VectorProxy implements InvocationHandler{
    private Object proxyObj;
    public VectorProxy(Object obj){
        this.proxyObj = obj;
    }
    public static Object factory(Object obj){
        Class<?> classType = obj.getClass();
        return Proxy.newProxyInstance(classType.getClassLoader(),
classType.getInterfaces(), new VectorProxy(obj));
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
        System.out.println("before calling: " + method);
        if(null != args){
            for(Object obj : args){
                System.out.println(obj);
            }
        }
        Object object = method.invoke(proxyObj, args);
        System.out.println("after calling: " + method);
        return object;
    }
    public static void main(String[] args)
    {
        List v = (List)factory(new Vector());
        System.out.println(v.getClass().getName());
        System.out.println("---------------1");
        v.add("New");
        System.out.println("---------------2");
        v.add("York");
        System.out.println("---------------3");
        System.out.println(v);
        System.out.println("---------------4");
        v.remove(0);
        System.out.println("---------------5");
        System.out.println(v);        
    }
}
运行结果:
$Proxy0
---------------1
before calling: public abstract boolean java.util.List.add(java.lang.Object)
New
after calling: public abstract boolean java.util.List.add(java.lang.Object)
---------------2
before calling: public abstract boolean java.util.List.add(java.lang.Object)
York
after calling: public abstract boolean java.util.List.add(java.lang.Object)
---------------3
before calling: public java.lang.String java.lang.Object.toString()
after calling: public java.lang.String java.lang.Object.toString()
[New, York]
---------------4
before calling: public abstract java.lang.Object java.util.List.remove(int)
0
after calling: public abstract java.lang.Object java.util.List.remove(int)
---------------5
before calling: public java.lang.String java.lang.Object.toString()
after calling: public java.lang.String java.lang.Object.toString()
[York]


3. 动态代理具体实现

Foo.java

public interface Foo{
    void doAction();
}


FooImpl.java

public class FooImpl implements Foo{
    public void doAction(){
        System.out.println("in FooImpl doAction!");
    }
}


FooImpl2.java

public class FooImpl2 implements Foo{
    public void doAction(){
        System.out.println("in FooImpl2 doAction!");
    }
}


CommonInvocationHandler.java

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class CommonInvocationHandler implements InvocationHandler{
    private Object target;
    public CommonInvocationHandler(Object target){
        this.target = target;
    }
    public CommonInvocationHandler(){
        
    }
    public void setTarget(Object target){
        this.target = target;
    }
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable{
        return method.invoke(target, args);
    }
}


Demo.java

import java.lang.reflect.Proxy;
public class Demo{
    public static void main(String[] args)    {
        CommonInvocationHandler handler = new CommonInvocationHandler();
        Foo f = null;
        handler.setTarget(new FooImpl());
        f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                new Class[] { Foo.class }, handler);
        f.doAction();
        System.out.println("-------------------");
        handler.setTarget(new FooImpl2());
        f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                new Class[] { Foo.class }, handler);
        f.doAction();
    }
}
运行结果:
in FooImpl doAction!
---------
in FooImpl2 doAction!
分享到:
评论

相关推荐

    java 简答可复用动态代理类

    - `Proxy`类是Java提供的动态代理的工厂,它可以根据一个接口生成实现了该接口的代理类的对象。这个代理类会动态地生成并实现接口的所有方法。 - `InvocationHandler`接口定义了一个处理方法调用的回调方法`invoke...

    java动态代理类的实例

    在Java中,静态代理是通过定义一个与被代理类实现相同接口的新类来实现的,而动态代理则在运行时动态生成此类,无需预先编写代理类的代码。 `java.lang.reflect.Proxy`类是Java动态代理的核心,它提供了创建代理...

    Java实现动态代理

    我们先来看Proxy类,它是Java动态代理的核心,它提供了一种机制,能够基于接口生成代理类的实例。 1. **Proxy类的使用**: - 首先,你需要有一个或多个接口,代理对象会实现这些接口。 - 然后,定义一个...

    对代理模式与Java动态代理类的理解

    对代理模式与Java动态代理类的理解说明

    java + 动态代理 + 动态代理实际应用场景

    1:静态代理出现的实际背景,静态代理时如何演化成动态代理 2: 动态代理demo 举例实际应用场景(载入数据库驱动的时候,使用AIDL与系统Servic...4: 动态代理使用到基础理论:Class.forName("xxxx") 得到Class类 。

    Java中动态代理的介绍及实例

    ### Java中动态代理的核心知识点详解 #### 一、动态代理概览 动态代理是Java反射机制的一个重要应用,主要用于在不修改目标对象源代码的情况下,为一个对象提供一个代理对象,这个代理对象能够控制对目标对象的...

    动态代理及生成的代理类

    动态代理及其生成的代理类,可以反编译查看其类的结构。

    java动态代理实现详解

    Java 动态代理是Java平台提供的一种强大的工具,它允许我们在运行时动态生成代理类,这些代理类可以实现一组指定的接口,同时还能在方法调用前后添加自定义的行为。这种机制大大简化了面向切面编程(AOP)和事件监听...

    java动态代理demo

    通过这个简单的Java动态代理demo,你可以了解到如何在实际项目中利用动态代理进行功能扩展,同时避免了为每个接口编写单独的代理类。这种技术可以极大地提高代码的可复用性和可维护性,是Java开发中一个强大的工具。

    java动态代理详细解析

    - **代码复用**:通过动态代理,可以编写一次通用的逻辑(如日志记录),然后在多个类中复用。 - **易测试**:代理类可以用于模拟复杂的依赖关系,简化单元测试。 - **扩展性**:动态代理允许在不修改原有代码的...

    Java中的动态代理

    ### Java中的动态代理知识点解析 #### 一、动态代理概念 在Java中,动态代理是一种设计模式,它允许我们创建一个对象来代表另一个对象。这种模式通常用于在不修改目标对象的情况下,为对象添加额外的功能或者行为...

    java动态代理实例

    Java动态代理是Java语言提供的一种在运行时创建代理对象的技术,它允许我们为已存在的接口创建代理类,以便在调用真实目标对象的方法时添加额外的功能或行为。在这个实例中,我们将深入探讨Java动态代理的核心概念,...

    java jdk 动态代理 演示demo

    在静态代理中,我们通过编写额外的代理类来实现这一目标,但在动态代理中,代理类是在运行时生成的,无需预先编写代码。 Java JDK提供了`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口,...

    JAVA类加载机制与动态代理

    - **动态语言支持**:例如使用`java.lang.reflect.Proxy`类来创建动态代理类。 - **自定义代码生成**:通过编写代码来手动生成代理类的字节码。 ##### 2.2 动态代理的概念 动态代理允许我们为一个接口创建一个代理...

    Java代理模式Java动态代理

    ### Java代理模式与Java动态代理详解 #### 一、代理模式概述 代理模式是一种软件设计模式,它在客户端和目标对象之间提供了一种间接层。这种模式的主要目的是控制客户端对目标对象的访问,并且可以在不修改原有...

    java Proxy 动态代理

    在Java中,动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类是用于创建一个代理对象,而InvocationHandler接口则定义了代理对象调用方法时的行为。 1. **...

    JAVA静态代理和动态代理

    总结来说,Java的静态代理适用于代理类较少且代理逻辑相对固定的情况,而动态代理则在代理类数量不确定或者代理逻辑可能变化时更为合适。两者都可以实现为原始对象添加附加功能,但动态代理在灵活性和代码维护方面...

    Java动态代理两种实现方式

    不过,Cglib生成代理类的速度比JDK慢,且内存占用稍高。 总结来说,Java动态代理为开发者提供了灵活的代码扩展机制,可以根据实际需求选择适合的实现方式。JDK动态代理适用于接口丰富的场景,而Cglib更适合对性能有...

Global site tag (gtag.js) - Google Analytics