算法介绍:在代理模式中,两个对象参与处理用一个请求,接收地请求有代理对象委托给真实对象处理,通过代理对象控制请求的访问。代理对象在客户端程序和真实目标对象起一个中间桥梁的作用, 通过使用对象聚合代替继承,有效地降低了软件模块之间地耦合度。
jdk动态代理结构图分析
JDK动态代理(代理接口)
/** * @author bo * @Date: 2019/5/13 16:38 */ public class DynamicClient { public static void main(String[] args) { // 真实处理对象 InvocationHandler handler = new TargetImpl(); //创建代理类实例对象 ITarget target = (ITarget) Proxy.newProxyInstance(ITarget.class.getClassLoader(), new Class[]{ITarget.class}, handler); //操作方法(实际执行的是)handler中的invoke方法 target.operation(); } }
/** * ITarget接口 * @author bo * @Date: 2019/5/13 16:36 */ public interface ITarget { /** * 操作方法 */ void operation(); }
/** * ITarget目标代理类实现类 * @author bo * @Date: 2019/5/13 16:37 */ public class TargetImpl implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) { System.out.println("---method" + method.getName()); System.out.println("---动态代理类实现"); return null; } }
Cglib代理(被代理对象,需要引入asm和cglib依赖)
/** * @Author:bo * @Date: 2019/9/29 8:58 * @Version 1.0 */ public class DynamicClient { public static void main(String[] args) { // 通过 CGLIB 动态代理获取代理对象的过程 Enhancer enhancer = new Enhancer(); // 设置 enhancer 对象的父类 enhancer.setSuperclass(HelloService.class); // 设置 enhancer 的回调对象 enhancer.setCallback(new MethodInterceptor()); // 创建代理对象 HelloService proxy = (HelloService) enhancer.create(); // 通过代理对象调用目标方法 proxy.sayOthers("hello"); } }
/** * @Author:bo * @Date: 2019/9/29 8:58 * @Version 1.0 */ public class HelloService { public HelloService() { System.out.println("HelloService 构造"); } /** * 该方法不能被子类覆盖,Cglib 是无法代理 final 修饰的方法的 */ public String sayOthers(String name) { System.out.println("HelloService:sayOthers>>" + name); return null; } }
/** * @Author:bo * @Date: 2019/9/29 8:58 * @Version 1.0 */ public class MethodInterceptor implements net.sf.cglib.proxy.MethodInterceptor { /** * sub:cglib 生成的代理对象 * method:被代理对象方法 * objects:方法入参 * methodProxy: 代理方法 */ @Override public Object intercept(Object sub, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("======插入前置通知======"); Object object = methodProxy.invokeSuper(sub, objects); System.out.println("======插入后者通知======"); return object; } }
代理模式的应用非常广泛,在JDK中就为我们引入了动态代理技术。
动态代理,就是一个系统在没有统一接口的情况下,在运行时,动态地对那些接口不同地对象提供代理支持。
jdk动态代理的核心是InvocationHandler接口,要使用动态代理必须实现该接口。
这个接口的委派任务是在invoke(Object proxy,Method m,Object[] args)方法里实现的