Skip to content

代理模式是指,为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户类和目标对象之间起到中介的作用。说直白一点就是在不修改目标对象的基础上,使用代理对象来增强目标对象的业务逻辑方法。

代理模式分为:静态代理和动态代理(jdk动态代理和cglib动态代理)

静态代理就是:代理类在程序运行前就确定好了和目标类的关系,在编译期就实现了。其中静态代理的缺点在于:

1、代码复杂,不便于管理:试想对于代理类,需要和目标类实现相同接口即每个代理类都要实现目标类的的方法,会出现代码重复,且考虑到如果接口增加一个方法,其所有实现类都要重写,维护也麻烦。

2、代理类依赖于目标类:当代理类考虑代理多个服务的时候,不便于实现

动态代理是在程序运行期间根据jvm反射机制动态生成的。

jdk动态代理:基于java反射机制实现的。具体通过使用java.lang.reflect 包提供三个类支持代理模式 Proxy, Method和 InovcationHandler。(要求:求目标对象必须实现接口)

public interface UsbSell {
    Object sell(float amount);
}



public class UsbFactory implements UsbSell {

public Object sell(float amount) {
    float price = 0;
    if (amount > 100){
        price = (float) (amount * (1 + 0.2));
    }else {
        price = (float) (amount * (1 + 0.5));
    }
    return price;
	}
}






public class ProxySeller {

private Object target;

public ProxySeller() {
}

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

public Object getProxy(){
    return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            float res = (Float) method.invoke(target,args);
            System.out.println("=="+res);
            return proxy;
        }
    });
}

}



public class Main {

public static void main(String[] args) {
    UsbFactory factory = new UsbFactory();
    ProxySeller seller = new ProxySeller(factory);
    UsbSell proxy = (UsbSell)seller.getProxy();
    UsbSell s = (UsbSell)proxy.sell(50);
    s.sell(50);
}

}

cglib动态代理:一个开源项目。对于无接口的类,要为其创建动态代理,就要使用 CGLIB 来实现。CGLIB 代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代理对象。所以,使用CGLIB 生成动态代理,要求目标类必须能够被继承,即不能是 final 的类。

	public class Saller {

public float sell(int amount){
    float price = 100;
    if (amount > 100){
        price = (float) (price * (1 + 0.2));
    }else {
        price = (float) (price * (1 + 0.5));
    }
    return price;
}

}



public class ProxySaller implements MethodInterceptor {

private Object target;

public ProxySaller() {

}

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

public Object getProxySaller(){
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(target.getClass());
    enhancer.setCallback(this);
    Saller saller = (Saller) enhancer.create();
    return saller;
}

public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    Float price = (Float) methodProxy.invoke(target,objects);
    System.out.println("==="+price);
    return price;
}
}



public class Main {

public static void main(String[] args) {
    Saller saller = new Saller();
    ProxySaller proxySaller = new ProxySaller(saller);
    Saller proxy = (Saller) proxySaller.getProxySaller();
    proxy.sell(100);
}

}

Released under the MIT License.