工学1号馆

home

java核心系列15-动态代理

By Wu Yudong on June 20, 2015

原创文章,转载请注明: 转载自工学1号馆

动态代理作为代理模式的一种扩展形式,广泛应用于框架(尤其是基于AOP的框架)的设计与开发,本文将通过实例来讲解Java动态代理的实现过程。

通常情况下,代理模式中的每一个代理类在编译之后都会生成一个class文件,代理类所实现的接口和所代理的方法都被固定,这种代理被称之为静态代理(Static Proxy)。那么有没有一种机制能够让系统在运行时动态创建代理类?答案就是本文将要介绍的动态代理(Dynamic Proxy)。动态代理是一种较为高级的代理模式,它在事务管理、AOP(Aspect-OrientedProgramming,面向方面编程)等领域都发挥了重要的作用。有关代理模式的基础知识,可以参考《代理模式(Proxy)

从JDK 1.3开始,Java语言提供了对动态代理的支持,Java语言实现动态代理时需要用到位于java.lang.reflect包中的一些类,现简要说明如下:

(1) Proxy类

Proxy类提供了用于创建动态代理类和实例对象的方法,它是所创建的动态代理类的父类,它最常用的方法如下:

  • public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces):该方法用于返回一个Class类型的代理类,在参数中需要提供类加载器并需要指定代理的接口数组。
  • public static Object newProxyInstance(ClassLoader loader, Class<?>[]interfaces, InvocationHandler h):该方法用于返回一个动态创建的代理类的实例,方法中第一个参数loader表示代理类的类加载器,第二个参数interfaces表示代理类所实现的接口列表,第三个参数h表示所指派的调用处理程序类。

(2) InvocationHandler接口

InvocationHandler接口是代理处理程序类的实现接口,该接口作为代理实例的调用处理者的公共父类,每一个代理类的实例都可以提供一个相关的具体调用处理者(InvocationHandler接口的子类)。在该接口中声明了如下方法:

public Object invoke(Objectproxy, Method method, Object[] args):该方法用于处理对代理类实例的方法调用并返回相应的结果,当一个代理实例中的业务方法被调用时将自动调用该方法。

proxy表示我们所代理的那个真实对象;

method表示我们所要调用真实对象的某个方法的Method对象;

args表示调用真实对象某个方法时接受的参数

      动态代理类需要在运行时指定所代理真实主题类的接口,客户端在调用动态代理对象的方法时,调用请求会将请求自动转发给InvocationHandler对象的invoke()方法,由invoke()方法来实现对请求的统一处理。

先看java静态代理的例子:

ISubject:

public interface ISubject {
    public void request();
}

RealSubject(真实角色):

public class RealSubject implements ISubject{
    @Override
    public void request() {
        System.out.println("realSubject requesting");
    }
}

ProxySubject(代理类):

public class ProxySubject implements ISubject{
    private RealSubject realSubject;
    public ProxySubject() {
        realSubject = new RealSubject();
    }

    @Override
    public void request() {
        System.out.println("do something before");
        realSubject.request();
        System.out.println("do something after");
    }
}

Test(客户端测试):

public class Test {
    public static void main(String[] args) {
        ISubject proxySubject = new ProxySubject();
        proxySubject.request();
    }
}

再看java动态代理的例子:

ISubject:

public interface ISubject {
    public void request();
}

RealSubject:

public class RealSubject implements ISubject{
    @Override
    public void request() {
        System.out.println("realSubject requesting");
    }
}

SubjectInvocationHandler(调用处理类):

public class SubjectInvocationHandler implements InvocationHandler{  //实现InvocationHandler接口
    // 这个就是我们要代理的真实对象
	private Object obj;
	
    // 构造方法,给我们要代理的真实对象赋初值
    public SubjectInvocationHandler(Object obj) {
        this.obj = obj;
    }
    
    /**
     * 生成代理类工厂
     * @param realObj
     * @return 返回生成的代理类
     */
    public static Object getProxyInstanceFactory(Object realObj){
        Class<?> classType = realObj.getClass();
        return Proxy.newProxyInstance(classType.getClassLoader(), 
                classType.getInterfaces(), new SubjectInvocationHandler(realObj));
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("before");
        method.invoke(obj, args);
        System.out.println("after");
        return null;
    }
}

Test:

public class Test {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        ISubject subject = (ISubject)SubjectInvocationHandler.getProxyInstanceFactory(realSubject);
        subject.request();
    }
}

 

如果文章对您有帮助,欢迎点击下方按钮打赏作者

Comments

No comments yet.
To verify that you are human, please fill in "七"(required)