代理模式
所谓代理模式,代理就是类似中介的意思,比如买房,可以选择自己买房或者委托中介(代理)买房,如果委托中介,中介除了买房,还会做一些额外的事情。

静态代理
买房接口:
public interface BuyHouse { void buyHouse(); }
自己买房实现:
public class BuyHouseImpl implements BuyHouse { @Override public void buyHouse() { System.out.println("buy house!"); } }
中介买房实现:
public class BuyHouseProxy implements BuyHouse { private BuyHouse buyHouse; public BuyHouseProxy(final BuyHouse buyHouse){ this.buyHouse=buyHouse; } @Override public void buyHouse() { System.out.println("before"); buyHouse.buyHouse(); System.out.println("after"); } }
客户类测试:
public class Client { public static void main(String[] args) { // 自己买房 System.out.println("自己买房:"); BuyHouse buyHouse=new BuyHouseImpl(); buyHouse.buyHouse(); System.out.println(); // 通过中介(代理)买房 System.out.println("通过中介买房:"); BuyHouse buyHouseProxy=new BuyHouseProxy(buyHouse); buyHouseProxy.buyHouse(); } }
输出结果:

优点:可以对某个已经实现的功能做扩充,而不更改原来的类。
缺点:一个中介只能给某个类提供服务,不能给其它类做代理。
jdk动态代理
动态代理就是通过反射把代理类中的target成员由买房服务换成通用的Object,这样这个代理就可以给任何服务提供代理。
动态代理类:
public class DynamicProxyHandler implements InvocationHandler { private Object object; public DynamicProxyHandler(final Object object){ this.object=object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before"); Object result=method.invoke(object,args); System.out.println("after"); return result; } }
客户类:
public class Client { public static void main(String[] args) { // 自己买房 System.out.println("自己买房:"); BuyHouse buyHouse=new BuyHouseImpl(); buyHouse.buyHouse(); System.out.println(); // 通过静态中介(代理)买房 System.out.println("通过静态中介买房:"); BuyHouse buyHouseProxy=new BuyHouseProxy(buyHouse); buyHouseProxy.buyHouse(); // 通过动态中介(代理)买房 System.out.println("通过动态中介买房:"); BuyHouse dynamicProxy= (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(),new Class[]{BuyHouse.class},new DynamicProxyHandler(buyHouse)); dynamicProxy.buyHouse(); } }
注意Proxy.newProxyInstance()方法接受三个参数:
ClassLoader loader:指定当前目标对象使用的类加载器,获取加载器的方法是固定的Class<?>[] interfaces:指定目标对象实现的接口的类型,使用泛型方式确认类型InvocationHandler:指定动态处理器,执行目标对象的方法时,会触发事件处理器的方法
CGLIB动态代理
静态代理和jdk动态代理都需要业务类有接口interface,对于没有接口的业务类,就需要用cglib代理了。
cglib的动态代理是基于子类的动态代理,不需要目标对象实现接口,要求被代理类不能由final修饰。
public class CglibProxy implements MethodInterceptor { private Object target; public Object getInstance(final Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); enhancer.setCallback(this); return enhancer.create(); } public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("买房前准备"); Object result = methodProxy.invoke(object, args); System.out.println("买房后装修"); return result; } }
客户类:
public class CglibProxyTest { public static void main(String[] args){ BuyHouse buyHouse = new BuyHouseImpl(); CglibProxy cglibProxy = new CglibProxy(); BuyHouseImpl buyHouseCglibProxy = (BuyHouseImpl) cglibProxy.getInstance(buyHouse); buyHouseCglibProxy.buyHosue(); } }
---
参考:

浙公网安备 33010602011771号