Cglib的动态代理
Posted linsky
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cglib的动态代理相关的知识,希望对你有一定的参考价值。
Cglib是基于类的代理,不需要基于接口,会生成目标对象类型的子对象,所以当需要被代理的类没有继承接口时,就可以使用Cglib代理。
过程如图所示:
Cglib有三种类似的方式,下面一一举例,可能比较肤浅:
目标类:
1 /** 2 * @author o_0sky 3 * @date 2019/2/20 21:51 4 */ 5 public class ProductService { 6 public void save() { 7 System.out.println("存钱"); 8 } 9 10 public int find() { 11 System.out.println("查询剩余"); 12 return 100; 13 } 14 }
方式一(工厂直接实现MethodInterptor接口):
1 import org.springframework.cglib.proxy.Enhancer; 2 import org.springframework.cglib.proxy.MethodInterceptor; 3 import org.springframework.cglib.proxy.MethodProxy; 4 5 import java.lang.reflect.Method; 6 7 /** 8 * @author o_0sky 9 * @date 2019/2/21 22:02 10 */ 11 public class CglibFactory implements MethodInterceptor { 12 //声明一个对象引用 13 private Object target; 14 15 //注入代理对象 16 public CglibFactory(Object target) { 17 this.target = target; 18 } 19 20 //获取代理对象 21 public Object getProxyObject() { 22 //代理对象生成器 23 Enhancer enhancer = new Enhancer(); 24 //获取目标对象.class 25 enhancer.setSuperclass(target.getClass()); 26 //获取目标对象类型的子类型 27 enhancer.setCallback(this); 28 //生成代理对象并返回 29 Object proxy = enhancer.create(); 30 return proxy; 31 } 32 33 /** 34 * @param o (代理对象) 35 * @param method (目标对象的方法对象) 36 * @param args(目标对象的方法的参数的值) 37 * @param methodProxy (代理对象的方法对象) 38 * @return 39 * @throws Throwable 40 */ 41 @Override 42 public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { 43 //给目标对象的目标方法增强功能 44 if ("sava".equals(method.getName())) { 45 date(); 46 } 47 //其他方法不作更改,照常执行,有返回值的返回 48 Object invoke = method.invoke(target, args); 49 return invoke; 50 } 51 52 //增强的保存日志方法 53 private static void date() { 54 System.out.println("操作日志保存了!"); 55 } 56 }
方式二(内部类实现MethodInterptor):
1 import org.springframework.cglib.proxy.Enhancer; 2 import org.springframework.cglib.proxy.MethodInterceptor; 3 import org.springframework.cglib.proxy.MethodProxy; 4 5 import java.lang.reflect.Method; 6 7 /** 8 * @author o_0sky 9 * @date 2019/2/21 22:14 10 */ 11 public class CglibFactory1 { 12 private Object target; 13 14 private static void date() { 15 System.out.println("操作日志保存了!"); 16 } 17 18 public Object getProxyObject() { 19 Enhancer enhancer = new Enhancer(); 20 enhancer.setSuperclass(target.getClass()); 21 enhancer.setCallback(new MyImp()); 22 Object o = enhancer.create(); 23 return o; 24 } 25 26 class MyImp implements MethodInterceptor { 27 28 @Override 29 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 30 if ("save".equals(method.getName())) { 31 date(); 32 } 33 Object invoke = method.invoke(target, objects); 34 return invoke; 35 } 36 } 37 }
方式三(匿名内部类):
import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * @author o_0sky * @date 2019/2/21 22:20 */ public class CglibFactory3 { private Object target; private static void date() { System.out.println("操作日志保存了!"); } public Object getProxyObject() { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { if ("save".equals(method.getName())) { date(); } Object invoke = method.invoke(target, objects); return invoke; } }); return enhancer.create(); } }
实现类:
1 /** 2 * @author o_0sky 3 * @date 2019/2/21 22:24 4 */ 5 public class DTest { 6 public static void main(String[] args) { 7 ProductService productService =new ProductService(); 8 CglibFactory factory =new CglibFactory(productService); 9 ProductService proxyObject = (ProductService) factory.getProxyObject(); 10 proxyObject.save(); 11 System.out.println("~~~~~~~~~~~~~~~~~~~~"); 12 productService.find(); 13 } 14 }
达成效果:
以上是关于Cglib的动态代理的主要内容,如果未能解决你的问题,请参考以下文章