【Java笔记】Java动态代理

【Java笔记】Java动态代理

动态代理

作用:在不修改原方法的基础上对方法进行增强

基于接口的动态代理

JDK提供的Proxy类

创建代理对象的要求

  • 被代理类至少实现一个接口

如何创建代理对象

Proxy的newProxyInstance静态方法

 public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
参数描述
ClassLoader loader被代理类的类加载器。用于加载代理类字节码。
Class<?> interfaces被代理类实现接口的字节码数组。为了让代理对象和被代理对象有相同的方法。
InvocationHandler h用于提供增强的代码。一般都通过实现一个该接口的匿名内部类。

InvocationHandler接口

执行被代理对象的任何接口方法都会经过此接口中的invoke方法

public interface InvocationHandler {
   public Object invoke(Object proxy, Method method, Object[] args)
          throws Throwable;
}
参数描述
Object proxy代理对象的引用,一般不用
Method method当前执行的方法
Object[] args当前执行方法的参数
返回值描述
Object与被代理对象方法的返回值相同

示例

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface Animal() {
  void bark();
}

class Dog implements Animal {
  public void bark() {
    System.out.println("汪汪汪");
  }
}

public class TestDynamicProxy {
  public static void main(String[] args) {
    // 匿名内部类调用外部对象,外部对象必须用final修饰
    final Dog dog = new Dog();
    
    Animal animal = (Animal) Proxy.newProxyInstance(dog.getClass().getClassLoader(), 
                   dog.getClass().getInterfaces(),
                   new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("调用了" + method.getName() + "方法");
                Object obj = method.invoke(dog, args);
                return obj;
            }                                        
       });
    
    animal.bark();
    
  }
}
// 控制台输出
// 调用了bark
// 汪汪汪

缺陷

被代理对象必须实现至少一个接口

基于子类的动态代理

第三方cglib库

创建代理对象的要求

被代理类不能是最终类

如何创建代理对象

Enhancer的静态方法create

public static Object create(Class type, Callback callback)
参数描述
Class type需要扩展的类或者实现的接口。就是需要被代理对象类的字节码。
Callback callback用于所有方法的回调。这里一般实现此接口的子接口MethodInterceptor

MethodInterceptor接口

public interface MethodInterceptor
extends Callback
{ 
    public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,
                               MethodProxy proxy) throws Throwable;
}
参数描述
Object obj代理对象的引用,一般不用
java.lang.reflect.Method method当前执行的方法
Object[] args当前执行方法的参数
MethodProxy proxy当前执行方法的代理对象

示例

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;


class Cat {
   void bark() {
       System.out.println("喵喵喵");
   }
}

public class  {

    public static void main(String[] args) {
        final Cat cat = new Cat();

        Cat catProxy = (Cat) Enhancer.create(cat.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                System.out.println("调用的方法:" + method.getName());
                Object returnValue = method.invoke(cat, args);
                return returnValue;
            }
        });

        catProxy.bark();

    }
}

// 控制台输出
// 调用了bark
// 喵喵喵
# proxy 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×