Java设计模式之代理模式

xiaoxiao2021-02-28  107

静态代理

直接上代码。 汽车移动的接口

package com.ysk.proxy; public interface Moveable { void move(); }

汽车类实现移动接口

package com.ysk.proxy; import java.util.Random; public class Car implements Moveable{ @Override public void move() { try { System.out.println("汽车行驶中"); Thread.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } } }

代理类实现移动接口

package com.ysk.proxy; public class CarProxy implements Moveable{ private Car car; public CarProxy(Car car){ this.car=car; } @Override public void move() { System.out.println("汽车开始行驶"); car.move(); System.out.println("汽车开始行驶"); } }

测试类

package com.ysk.proxy; public class CarProxy implements Moveable{ private Car car; public CarProxy(Car car){ this.car=car; } @Override public void move() { System.out.println("汽车开始行驶"); car.move(); System.out.println("汽车开始行驶"); } }

JDK动态代理

代理类实现InvocationHandler接口,在类层面代理

package com.dl.jdkproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class LogHandler implements InvocationHandler{ //Object 为需要代理的类对象 private Object o; public LogHandler(Object o){ this.o=o; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开始记录日志"); method.invoke(o); System.out.println("结束记录日志"); return null; } }

测试类

package com.dl.jdkproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import com.ysk.proxy.Car; import com.ysk.proxy.Moveable; public class App { public static void main(String[] args) { Car car=new Car(); InvocationHandler h=new TimeHandler(car); Class<?> cls=car.getClass(); /** * loader 类加载器 * interfaces 实现接口 * h InvocationHandler */ Moveable moveable= (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h); moveable.move(); } }

cglib动态代理

一个简单的火车类

package com.dl.cglibproxy; public class Train { public void move() { System.out.println("火车行驶中..."); } }

实现cglib的MethodInterceptor接口

package com.dl.cglibproxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor { private Enhancer enhancer=new Enhancer(); public Object getProxy(Class<?> clazz){ enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } /** * obj 目标类的实例 m 目标方法的反射对象 args 方法的参数 proxy 代理类的实例 */ @Override public Object intercept(Object obj, Method m, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("日志开始..."); proxy.invokeSuper(obj,args); System.out.println("日志结束..."); return null; } }

测试类,只需要将我们需要代理的类传进去即可,比JDK代理使用更加方便

package com.dl.cglibproxy; public class App { public static void main(String[] args) { CglibProxy proxy=new CglibProxy(); Train train=(Train) proxy.getProxy(Train.class); train.move(); } }

总结

静态代理太过死板,不能从类的层面去代理我们的类,如果多加几个类(比如火车,自行车等等),仍需要去写很多代码去实现。 动态代理,从类的层面去加载,使我们可以同时适用于多个类。  JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理.

转载请注明原文地址: https://www.6miu.com/read-54085.html

最新回复(0)