从零并发框架(三)异步转同步注解+字节码增强代理实现( 四 )
通过动态代理进行代码增强 , SyncBs.newInstance().syncContext(context).execute(); 这里就是对于增强方法的执行 。
cglib 字节码增强package com.github.houbb.sync.core.support.proxy.cglib;import com.github.houbb.sync.api.api.ISyncContext;import com.github.houbb.sync.core.bs.SyncBs;import com.github.houbb.sync.core.core.SimpleSyncContext;import com.github.houbb.sync.core.support.proxy.ISyncProxy;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/** * CGLIB 代理类 * @author binbin.hou * date 2019/3/7 * @since 0.0.1 */public class CglibProxy implements MethodInterceptor, ISyncProxy {/*** 被代理的对象*/private final Object target;public CglibProxy(Object target) {this.target = target;}@Overridepublic Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {ISyncContext context = SimpleSyncContext.newInstance().method(method).params(args).target(target);return SyncBs.newInstance().syncContext(context).execute();}@Overridepublic Object proxy() {Enhancer enhancer = new Enhancer();//目标对象类enhancer.setSuperclass(target.getClass());enhancer.setCallback(this);//通过字节码技术创建目标对象类的子类实例作为代理return enhancer.create();}}
对于没有接口的方法 , 我们通过 cglib 进行代码增强 , 这点和 spring aop 是保持一致的 。
代理的调用我们把三种场景的代理都实现了 , 那么应该如何判断方法应该调用哪一个代理呢?
这里有一个基本是公用方法 , 如下:
/* * Copyright (c)2019. houbinbin Inc. * async All rights reserved. */package com.github.houbb.sync.core.support.proxy;import com.github.houbb.heaven.util.lang.ObjectUtil;import com.github.houbb.sync.core.support.proxy.cglib.CglibProxy;import com.github.houbb.sync.core.support.proxy.dynamic.DynamicProxy;import com.github.houbb.sync.core.support.proxy.none.NoneProxy;import java.lang.reflect.Proxy;/** *代理信息
我们根据类本身 , 选择调用的代理类 。
* *Created: 2019/3/8 10:38 AM *Project: async * * @author houbinbin * @since 0.0.1 */public final class SyncProxy {private SyncProxy(){}/*** 获取对象代理* @param泛型* @param object 对象代理* @return 代理信息* @since 0.0.6*/@SuppressWarnings("all")public staticT getProxy(final T object) {if(ObjectUtil.isNull(object)) {return (T) new NoneProxy(object).proxy();}final Class clazz = object.getClass();// 如果targetClass本身是个接口或者targetClass是JDK Proxy生成的,则使用JDK动态代理 。// 参考 spring 的 AOP 判断if (clazz.isInterface() || Proxy.isProxyClass(clazz)) {return (T) new DynamicProxy(object).proxy();}return (T) new CglibProxy(object).proxy();}}
(1)空对象 , 不做增强
(2)接口或者代理类 , 使动态代理实现
(3)其他使用 cglib 进行字节码增强 。
验证春种秋收 , 我们辛苦忙活到现在 , 终于可以验证一下自己的成果了 。
上述代码已经上传到 maven 仓库 , 实际可以直接调用 。
maven 项目依赖
入门测试业务代码通过 @Sync 指定需要转同步的方法 , 通过 @SyncCallback 指定回调方法 。
- 图解|什么是高并发利器NoSQL
- 怎么理解分布式、高并发、多线程
- 写给大忙人看的,MyBatis日志如何做到兼容常用的日志框架
- 为什么 Django 框架持续统治着 Python 开发?
- 点云分类的自动放大框架 PointAugment
- 深入理解Logger日志——框架绑定原理
- 理解真实世界中 Go 的并发 BUG
- Go 中的 Goroutine 和其他并发处理方案的对比
- 迅易科技|| 拥抱“云”,更懂“云”,企业云采用框架落地实践
- 安卓|打破传统安卓系统框架!OriginOS的UI设计果然不俗