java动态代理模式

java代理模式

如果按照最原始的方式来实现java的代理模式,就是一个类生成一个代理接口类,针对对应方法都嵌入想要处理的前置通知和后置通知。这样的坏处是每个类都会生成一个代理类,会浪费资源。jdk原生的Proxy代理类,从jvm层面上解决接口代理模式的问题。

目标接口


package com.proxy;

/**
 * Created by Dongbin.Yu on 2015/11/18.
 */
public interface Subject {

    public void handle();
}

目标类

package com.proxy;

/**
 * @author dongbin.yu
 * @version 1.0.0
 * @since 2015/11/18
 */
public class SubjectImpl implements Subject {

    @Override
    public void handle() {
        System.out.println("hello world!");
    }
}



重点是代理类,是对被代理类方法的增强,每个方法的调用都会调用invoke方法,相应的可以在里面自由处理前置通知,后置通知,异常通知。可以实现我们常见的日志,权限等功能。
package com.proxy;

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

/**
 * @author dongbin.yu
 * @version 1.0.0
 * @since 2015/11/18
 */
public class DelegateProxy implements InvocationHandler {

    private Object target; //目标类

    public DelegateProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("start proxy");
        Object result = method.invoke(target, args);
        System.out.println("end proxy");

        return result;
    }

}



这个是利用接口的特性来实现java类的代理,spring还结合cglib利用java的继承来实现代理的方式。
package com.proxy;

import java.lang.reflect.Proxy;

/**
 * @author dongbin.yu
 * @version 1.0.0
 * @since 2015/11/18
 */
public class MainProxy {

    public static void main(String[] args) {

        Subject subject = new SubjectImpl();
        DelegateProxy delegateProxy = new DelegateProxy(subject);

        Subject subjectProxy = (Subject)Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), delegateProxy); --这个动态生成的代理类也可以由handle来提供。

        subjectProxy.handle();

    }
}



调用的地方需要将这个handle处理器注册到这个代理类里面。大胆的猜测jvm虚拟机的内部其实动态的生成代理类的字节码,使用相同的ClassLoader和Interface来唯一绑定这个代理类。这种方式其实也面临着方法区动态生成的代理类的回收情形。



你可能感兴趣的:(java,jvm,proxy)