`

Java的代理及InvocationHandler 接口的用法

阅读更多
java中是利用InvocationHandler 类实现代理,这是一个回调接口。
其中java代理并不神秘,说穿了就是使用一个和代理对象(也叫目标对象,为免混淆,以下称目标对象)实现了同样接口的一个类(这个类就叫代理类),用户实际是使用这个代理类来完成相关功能,而并不是使用所代理的目标对象本身。其原理是在代理类中有一个目标对象的成员,代理类调用目标成员的方法完成业务。因为这个特点,很容易在调用方法之前或之后来处理一些其它业务,这也就是AOP的实质。
闲话少说,看代码说明问题。不使用InvocationHandler ,我们可以自己这样实现一个简单代理类:
//定义一个接口:

interface Greet
{
    void sayHello(String name);

    void goodBye();
}



//实现这个接口:

class GreetImpl implements Greet
{
    public void sayHello(String name)
    {
        System.out.println("Hello " + name);
    }

    public void goodBye()
    {
        System.out.println("Good bye.");
    }
}



//实现一个代理类

public class SimpleProxy implements Greet
{
    private Greet greet = null;

    SimpleProxy(Greet greet)
    {
        this.greet = greet;
    }

    public void sayHello(String name)
    {
        System.out.println("--before method sayHello");
        greet.sayHello(name);
        System.out.println("--after method sayHello");
    }

    public void goodBye()
    {
        System.out.println("--before method goodBye");
        greet.goodBye();
        System.out.println("--after method goodBye");
    }

    /**
     * @param args
     */
    public static void main(String[] args)
    {
        Greet greet = new SimpleProxy(new GreetImpl());//生成代理
        greet.sayHello("walter");
        greet.goodBye();

    }
}

再看看如果实现了InvocationHandler接口, 我们怎样实现代理。
还是要实现原来的Greet接口。 接口的实现还是GreetImpl。
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class DebugProxy implements java.lang.reflect.InvocationHandler
{
    private Object obj;

    public static Object newInstance(Object obj)
    {
        return java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(), new DebugProxy(obj));
    }

    private DebugProxy(Object obj)
    {
        //Greet接口的實現:GreetImpl
        this.obj = obj;
    }

    //Method m:調用的方法
    //Object[] args:方法要傳入的參數
    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
    {
        Object result;
        try
        {
            //自定義的處理
            System.out.println("--before method " + m.getName());
            //調用GreetImpl中方法
            result = m.invoke(obj, args);
        }
        catch(InvocationTargetException e)
        {
            throw e.getTargetException();
        }
        catch(Exception e)
        {
            throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
        }
        finally
        {
            System.out.println("--after method " + m.getName());
        }
        return result;
    }

    /**
     * @param args
     */
    public static void main(String[] args)
    {
        Greet tmp = new GreetImpl();
        
        Greet greet = (Greet) DebugProxy.newInstance(tmp);
        //生成的greet和tmp有相同的hashCode
        
        greet.sayHello("walter");
        greet.goodBye();
    }
}
//注:以上代码转摘自 
//http://blog.csdn.net/aladdinty/archive/2009/03/11/3982007.aspx



可以看出,由于java的代理机制,被代理对象必须实现接口。
那如果被代理对象没有实现接口,就没有办法进行代理了吗?当然是可以的,我们可以让代理类继承自被代理对象,这样用户也可以通过父类(被代理类)获取代理对象的引用。Cglib就是这样的实现原理。Cglib中类似于InvocationHandler接口的是MethodInterceptor接口,需要覆写其intercept(Object proxy, Method method, Object[] args,MethodProxy methodProxy)方法,看看下面的基于cglib的代理实现:
//引入cglib库略过
public class CGlibProxyFactory  implements MethodInterceptor{
    privaet Object targetObject;
    public Object createProxyIntance(Object targetObject){
    this.targetObject = targetObject;
	Enhnacer enhnacer = new Enhnacer();
	////cglib实际上创建的代理是目标对象的一个子类,覆盖了父类中所有非final方法
    enhnacer.setSuperclass(this.targetObject.getClass());
    // setCallback(callback)设置回调对象  callback是实现方法拦截器的一个类
    enhnacer.setCallback(this);
    return enhnacer.create();
}
    public Object intercept(Object proxy, Method method, Object[] args,MethodProxy methodProxy) throws Throwable{
        PersonServiceImpl bean = (PersonServiceImpl) this.targetObject;
    Object result = null;
        if(bean.getUser() != null){
	    result = methodProxy.invoke(targetObject, args);
        }
        return result;
    }
}

分享到:
评论

相关推荐

    Java动态代理实现 Proxy InvocationHandler

    `InvocationHandler`接口定义了代理对象调用方法时的处理逻辑。当通过代理对象调用方法时,实际执行的是`InvocationHandler`的`invoke`方法。`invoke`方法接收三个参数:代理对象、被调用的方法和方法调用的参数。...

    java InvocationHandler

    Java中的`InvocationHandler`接口是Java动态代理机制的核心组成部分,主要用在`java.lang.reflect`包下。这个接口提供了一种方法,使得我们可以在运行时创建具有特定行为的代理对象。这种行为通常体现在调用代理对象...

    Java代理模式Java动态代理

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

    java动态代理demo

    - `Main.java`: 主程序,创建代理对象并调用其方法,展示动态代理的使用。 通过这个简单的Java动态代理demo,你可以了解到如何在实际项目中利用动态代理进行功能扩展,同时避免了为每个接口编写单独的代理类。这种...

    java代理机制 JDK动态代理和cglib代理 详解

    1. **InvocationHandler接口** - `InvocationHandler`是JDK动态代理的核心,它定义了一个invoke()方法,该方法会在代理类调用目标方法时被触发。 - 我们需要实现`InvocationHandler`接口,重写invoke()方法,当...

    java动态代理 经典文章(word 2007格式的)

    2. **InvocationHandler接口**: 在Java动态代理机制中,`InvocationHandler`接口扮演着关键角色。它定义了一个`invoke()`方法,当代理对象的方法被调用时,实际上是调用了`InvocationHandler`的`invoke()`方法。这...

    InvocationHandler, Proxy机制

    `InvocationHandler`是Java标准库`java.lang.reflect`包中的一个接口,它的主要作用是在运行时处理对代理对象的方法调用。当通过`Proxy`类生成的代理对象上的任何方法被调用时,实际的工作都是由`InvocationHandler`...

    java中的三种代理模式

    InvocationHandler接口的`invoke()`方法在代理对象的方法调用时被触发,我们可以在`invoke()`方法中添加额外的逻辑。这种方式相比静态代理更灵活,不需要为每个目标对象创建单独的代理类。 3. **CGLIB代理** CGLIB...

    java动态代理(3)

    在Java.lang.reflect包下,动态代理主要涉及两个核心类:InvocationHandler接口和Proxy类。 **InvocationHandler接口** InvocationHandler接口定义了代理对象在被调用时执行的方法。它只有一个方法`invoke(Object ...

    java动态代理实例

    1. **InvocationHandler接口**:当调用代理对象的方法时,实际的执行逻辑是由实现了`InvocationHandler`接口的类来提供的。该接口包含一个`invoke`方法,它接收三个参数:代理对象、被调用的方法以及方法调用时传递...

    Java 动态代理和Cglib代理(二)

    1. 创建一个InvocationHandler接口的实现,定义代理对象如何处理方法调用。 2. 使用Proxy.newProxyInstance()方法,传入目标接口、InvocationHandler实例以及类加载器,生成代理对象。 3. 通过代理对象调用接口方法...

    Java 动态代理详解(学习资料)

    JDK 动态代理JDK 提供了 java.lang.reflect.Proxy 类和 java.lang.reflect.InvocationHandler 接口来支持动态代理。Proxy 类用于创建一个代理对象,而 InvocationHandler 接口则定义了代理对象的方法调用处理逻辑。...

    java动态代理机制

    使用Proxy类,我们可以通过传入InvocationHandler接口的实现来控制代理对象的行为。Proxy类提供了静态方法`newProxyInstance()`,它接收三个参数:ClassLoader(用于加载生成的代理类)、Interface[](代理类需要...

    Java动态代理两种实现方式

    Proxy类用于创建一个代理对象,而InvocationHandler接口定义了处理代理对象方法调用的逻辑。 #### 1. 创建InvocationHandler 首先,我们需要实现`InvocationHandler`接口,重写`invoke`方法。在`invoke`方法中,...

    java动态代理(2)

    在`Client.java`中,我们会先创建一个`InvocationHandler`的实例,然后使用`Proxy.newProxyInstance()`生成代理对象,最后通过代理对象来调用`Subject`接口的方法。`DynamicSubject.java`中的`InvocationHandler`...

    JAVA静态代理和动态代理

    Java的`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口提供了动态代理的支持。 1. 定义接口: ```java public interface Service { void doSomething(); } ``` 2. 创建...

    java之代理.pdf

    Java代理主要分为静态代理和动态代理。静态代理需要目标对象和代理对象都实现相同的接口,代理对象在编译时就已经确定,适用于简单场景。动态代理则更灵活,代理类和代理对象在运行时动态生成,不需要预先定义接口,...

    JAVA代理

    总结一下,`JAVA代理`涉及到的主要知识点包括: 1. **静态代理**:手动创建代理类,通过代理类对目标对象进行方法调用的拦截和增强。 2. **动态代理**:利用Java的`Proxy`类和`InvocationHandler`接口,动态地创建...

    java 动态代理 简单实例

    Java动态代理是Java语言提供的一种在运行时创建代理对象的技术,它允许我们为已存在的接口创建代理类,以便在调用方法时添加额外的功能或控制。动态代理在很多场景下非常有用,比如日志记录、性能监控、事务管理等。...

    Java设计模式——代理设计模式(静态代理和动态代理)

    3. **创建代理对象**:使用`Proxy.newProxyInstance()`方法动态生成代理对象,这个方法需要传入目标类的类加载器、目标类实现的接口数组以及`InvocationHandler`实例: ```java Service proxyService = (Service) ...

Global site tag (gtag.js) - Google Analytics