设计模式——代理模式
代理模式:对一个对象提供另外一个对象,可以在调用正式对象前进行操作,在之后也可以进行操作。
1:静态代理
public interface Shopping { void shop(); }
public class ShoppingImpl implements Shopping { @Override public void shop() { System.out.println("我要去买东西!"); } }
public class ShoppingProxy implements Shopping { private Shopping shopping; public ShoppingProxy(Shopping shopping) { this.shopping = shopping; } @Override public void shop() { System.out.println("准备钱"); shopping.shop(); System.out.println("付账走"); } }
public class ProxyTest { public static void main(String[] args) { Shopping shopping = new ShoppingImpl(); Shopping shopping1 = new ShoppingProxy(shopping); shopping1.shop(); } }
静态代理
优点:在不修改原类的基础上,可以进行功能的修改。
缺点:当我创建一个方法的时候,就需要手动的修改代理类。
2:动态代理
public class DynamicProxy implements InvocationHandler { private Shopping shopping; public DynamicProxy(Shopping shopping) { this.shopping = shopping; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("准备钱"); Object result = method.invoke(shopping,args); System.out.println("付账走"); return result; } public Object newProxyInstance(){ return Proxy.newProxyInstance(shopping.getClass().getClassLoader(), shopping.getClass().getInterfaces(),this); } }
public class ProxyTest { public static void main(String[] args) { Shopping shopping = new ShoppingImpl(); DynamicProxy dynamicProxy = new DynamicProxy(shopping); shopping = (Shopping)dynamicProxy.newProxyInstance(); shopping.shop(); } }
Proxy.newProxyInstance的三个参数
ClassLoader loader, //制定类的加载器
Class<?>[] interfaces, //制定目标实现的接口
InvocationHandler h //动态处理器,执行目标方法时,会触发动态处理器
虽然动态代理减少了静态代理工作量,但是唯一的缺点就是必须依赖接口。
3:CJLIB动态代理
public class CglibProxy implements MethodInterceptor { private Object target; public Object getInstance(final Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
//设置enhancer的父类
enhancer.setSuperclass(this.target.getClass());
//设置enhancer的回调对象
enhancer.setCallback(this);
//创建代理对象
return enhancer.create();
}
/** * o:cglib生成的代理对象 * method:被代理对象方法 * objects:方法入参 * methodProxy: 代理方法 */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("准备钱"); Object result = methodProxy.invokeSuper(o,objects); System.out.println("付账走"); return result; } }
public class ProxyTest { public static void main(String[] args) { Shopping shopping = new ShoppingImpl(); CglibProxy cglibProxy = new CglibProxy(); ShoppingImpl shopping1 = (ShoppingImpl)cglibProxy.getInstance(shopping); shopping1.shop(); } }
cglib主要是针对类的代理,生成一个子类,覆盖所有的方法,但是final是不能被代理的