频道栏目
首页 > 程序开发 > 软件开发 > 其他 > 正文
JDK动态代理和CGLIB代理解析
2018-08-29 16:03:07           
收藏   我要投稿

JDK代理

这里写图片描述

通过实现接口实现

通过动态代理,给普通的对象生成代理对象,对其中的方法进行前置和后置的处理
例如spring的事务

使用动态代理的五大步骤
1.通过实现InvocationHandler接口来自定义自己的InvocationHandler;<喎"/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjIuzai5/VByb3h5LmdldFByb3h5Q2xhc3O78bXDtq/MrLT6wO3A4DwvcD4NCjxwPjMuzai5/be0yeS7+tbGu/G1w7T6wO3A4LXEubnU7Le9t6ijrLe9t6jHqcP7zqpnZXRDb25zdHJ1Y3RvcihJbnZvY2F0aW9uSGFuZGxlci5jbGFzcyk8L3A+DQo8cD40Ls2ouf25udTsuq/K/bvxtcO0+sDtttTP87KivavX1Lao0uW1xEludm9jYXRpb25IYW5kbGVyyrXA/bbUz/O0q86qss7K/bSryOs8L3A+DQo8cD41Ls2ouf20+sDtttTP87X308PEv7Hqt723qDwvcD4NCjxwcmUgY2xhc3M9"brush:java;"> //接口 public interface MyBuyInterface { void buy(String goods); } //实现这这个接口,也就是后面需要代理的对象 public class MyBuyClass implements MyBuyInterface { @Override public void buy(String goods) { System.out.println("我买了 " + goods); } } //实现自己的InvocationHandler //实现InvocationHander接口 public class MyInvocationHandler implements InvocationHandler{ //需要被代理的对象 private Object target; public MyInvocationHandler(Object target) { super(); this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //前置处理 System.out.println(new Date()); //这里是实际调用实际的方法 Object res = method.invoke(target, args); //后置处理 System.out.println("买完了"); return res; } } //进行实际的调用 public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //方法一 //获取代理类 Class proxyClass = Proxy.getProxyClass(MyBuyInterface.class.getClassLoader(), MyBuyInterface.class); //获取代理类的构造方法,传入InvocationHandler接口 Constructor constructor = proxyClass.getConstructor(InvocationHandler.class); //通过构造方法创建代理对象,传入自定义invocationHandler MyBuyInterface obj = (MyBuyInterface) constructor.newInstance(new MyInvocationHandler(new MyBuyClass())); //调用方法,此时会调用自定义invocationHandler的invoke方法 obj.buy("苹果"); //方法二 //上面的几步可以通过下面这个方法合并为一步 MyBuyInterface oobbjj = (MyBuyInterface) Proxy.newProxyInstance(MyBuyInterface.class.getClassLoader(), new Class[] {MyBuyInterface.class}, new MyInvocationHandler(new MyBuyClass())); oobbjj.buy("梨子"); }

运行结果

Tue Aug 28 12:15:37 CST 2018
我买了 苹果
买完了
Tue Aug 28 12:15:37 CST 2018
我买了 梨子
买完了

CGLIB代理

CGLIB会让生成的代理类继承被代理类,并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。在CGLIB底层,其实是借助了ASM这个非常强大的Java字节码生成框架。

//自定义方法拦截器,实现MethodInterceptor 接口
public class MyMethodInterceptor implements MethodInterceptor {

 @Override
 public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
  System.out.println(new Date());
  Object res = proxy.invokeSuper(obj, arg);
  System.out.println("买完了");
  return res;
 }

}

//进行调用
public static void main(String[] args) {
  Enhancer enhancer = new Enhancer();  
  //设置父类
  enhancer.setSuperclass(MyBuyClass.class);  
  //设置方法拦截器
  enhancer.setCallback(new MyMethodInterceptor());  
  //生成代理类
  MyBuyClass myBuyClass = (MyBuyClass)enhancer.create();
  myBuyClass.buy("梨子");
 }

//运行结果
Tue Aug 28 13:37:38 CST 2018
我买了 梨子
买完了

代理类将委托类作为自己的父类并为其中的非final委托方法创建两个方法,一个是与委托方法签名相同的方法,它在方法中会通过super调用委托方法;另一个是代理类独有的方法。在代理方法中,它会判断是否存在实现了MethodInterceptor接口的对象,若存在则将调用intercept方法对委托方法进行代理

点击复制链接 与好友分享!回本站首页
上一篇:欧拉路径和欧拉回路及其应用解析
下一篇:SpringBoot,Springmvc Spring 知识总结
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站