代理模式:
再不改变源代码的情况下,为程序添加新的功能,我感觉有点象python中的包装器,提高了代码的可扩展性;
代理模式分为:静态代理和动态代理;动态代理又分接口形式()和继承形式(CGlib方式)
用接口形式的代理规则:
- 定义接口
- 客户和代理进行互通
- 在代理类中被代理者作为属性
静态代理 static proxy
//被代理类
public class PhoneFactory implements Phone { @Override public String getPhone(String pName) { if(pName.equals("IPhone")){ return "我有啊!就是贵"; }else if (pName.equals("MI")){ return "谁都能买的起,价格实惠!"; } return pName; } @Override public String getPhonePart(String ppName) { return ppName; } }
//接口
//手机规范接口
public interface Phone { public String getPhone(String pName); public String getPhonePart(String ppName); }
//代理类
public class PhoneProxy implements Phone{ private Phone phone; public PhoneProxy(Phone phone){ this.phone = phone; } @Override public String getPhone(String pName) { System.out.println("我加了1000元!"); return phone.getPhone(pName); } @Override public String getPhonePart(String ppName) { System.out.println("零件我也加钱"); return phone.getPhonePart(ppName); } }
//测试
public static void main(String[] args) {
Phone pFactory = new PhoneFactory();
Phone pProxy = new PhoneProxy(pFactory);
System.out.println(pProxy.getPhone("IPhone"));
}代理前的输出:
》》我有啊!就是贵
代理后的输出:
》》我加了1000元!
》》我有啊!就是贵
-
缺点介绍:
-
需要实现每一个代理累的方法
-
动态代理(接口的形式)
- 完善了静态代理的缺点
- 缺点是需要接口
- 步骤:
- 代理类实现InvocationHandler接口
- 重写invoke方法,并创建一个全局属性用来存被代理对象
//被代理类
public class CarFactory implements Car { @Override public String buyCar(String cname) { if (cname.equals("大车")) { return "卡车"; } else if (cname.equals("小车")) { return "厢货"; } return cname; } } @Override public String buyCarPart(String cPartName) { return cPartName; }
//代理处理器
public class DynamicInterface implements InvocationHandler { private Object object; public Object getObject() { return object; } public void setObject(Object object) { this.object = object; } public DynamicInterface(Object object) { this.object = object; } public DynamicInterface() { } //第一个参数是自己,第二个参数是调用的方法,第三个参数是传的参数 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我赚差价,加了10000!"+"调用了:"+method.getName()+"方法!"); Object invoke = method.invoke(object, args); return invoke; } }
//规范接口类
public interface Car { public String buyCar(String cname); public String buyCarPart(String cPartName); }
//测试
public static void main(String[] args) { Car car = new CarFactory(); //代理处理器,将被代理对象传入代理类里 DynamicInterface di = new DynamicInterface(car); //通过 Proxy 的静态工厂方法 newProxyInstance 创建动态代理类实例。 //第一个参数:类加载器;第二个参数:类实现的全部接口;第三个参数:调用的处理器 Car car1 = (Car) Proxy.newProxyInstance(di.getClass().getClassLoader(),car.getClass().getInterfaces(),di); System.out.println(car1.buyCar("大车")); }
第二种动态代理方式(继承的形式)
- 通过使用CGlib方式对方法进行拦截,从而达到不改变原有代码的基础上添加前后置通知处理并且不依赖接口
- 实现步骤:
- 代理类实现MethodInterceptor接口
- 重写intercept方法
- 使用:
//被代理类
public class ComputerFactory { public String getComputer(String name) { return name + "牌电脑1000元"; } public String getComputerPart(String partNname) { return partNname + "种零件100元"; } }
//代理类
public class DynamicExtends implements MethodInterceptor { // o:被继承对象,被代理对象;method:代理前的方法;objects:传进来的参数;methodProxy:代理后的方法 @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("哈哈我又来赚差价了调用了"+methodProxy.getSuperName()+"方法"); System.out.println("method:"+method.getName()); //method:代理之前的方法;methodProxy:代理之后的方法 Object o1 = methodProxy.invokeSuper(o, objects); return o1; } }
//测试
public static void main(String[] args) { Enhancer cg = new Enhancer(); cg.setSuperclass(ComputerFactory.class);//传的是被代理的类实例 cg.setCallback(new DynamicExtends());//传的是代理类 //创建继承后的对象 ComputerFactory computerFactory = (ComputerFactory) cg.create(); System.out.println(computerFactory.getComputer("联想")); }