事在人为智能时代之至

咱们解Spring是透过JDK或者CGLib实现动态代理的,今天我们讨论一下JDK实现动态代理的规律。

文/田羽 (微:mailvincent)

一、简述

网易CEO的丁磊最近为大家极力推荐了吴军的《智能时代》,同时涉嫌“人工智能技术在未来十年里将会晤潜移默化我们活的全部,我们的家电、娱乐、各种劳动经验,将会起颠覆性改变。”

Spring在解析Bean的概念之后会以Bean的定义生成一个BeanDefinition对象又由BeanDefinitionHolder对象有。在这个进程中,如果Bean需要为通切入,BeanDefinition会给还更换成为一个proxyDefinition(其实为是一个BeanDefinition对象,只不过描述的是一个ProxyFactoryBean)。ProxyFactoryBean是一个贯彻了FactoryBean的接口,用来变化于被切入的目标。Spring
AOP的贯彻多是经ProxyFactoryBean实现的。我们今天谈论的要害也是以此类似。
  以议论ProxyFactoryBean之前,我们先押一下一个BeanDefinition转换成为proxyDefintion的过程。

吴军在智能时代提出的一个口号:要么改为那么2%的受益人,要么被裁。

那么《智能时代》里究竟写了哪的同等种状况?已然来临的智能时代对咱,尤其是活经理的劳作措施、思维方式会带动怎样影响?

当吴军眼里,AlphaGo在围棋的对决中非常收获全胜,到底意味着什么?Google的无人汽车怎么就使为车手同志等全都失业了?

再次进一步,在智能时代背后,未来底活之商业模式和形态会发生什么样变化?会出什么样产品时?作为产品人的我们准备好了吧?

public final BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definitionHolder, ParserContext parserContext) {
        BeanDefinitionRegistry registry = parserContext.getRegistry();

        // get the root bean name - will be the name of the generated proxy factory bean
        String existingBeanName = definitionHolder.getBeanName();
        BeanDefinition targetDefinition = definitionHolder.getBeanDefinition();
        BeanDefinitionHolder targetHolder = new BeanDefinitionHolder(targetDefinition, existingBeanName + ".TARGET");

        // delegate to subclass for interceptor definition
        BeanDefinition interceptorDefinition = createInterceptorDefinition(node);

        // generate name and register the interceptor
        String interceptorName = existingBeanName + "." + getInterceptorNameSuffix(interceptorDefinition);
        BeanDefinitionReaderUtils.registerBeanDefinition(
                new BeanDefinitionHolder(interceptorDefinition, interceptorName), registry);

        BeanDefinitionHolder result = definitionHolder;

        if (!isProxyFactoryBeanDefinition(targetDefinition)) {
            // create the proxy definition 这里创建proxyDefinition对象,并且从原来的BeanDefinition对象中复制属性
            RootBeanDefinition proxyDefinition = new RootBeanDefinition();
            // create proxy factory bean definition
            proxyDefinition.setBeanClass(ProxyFactoryBean.class);
            proxyDefinition.setScope(targetDefinition.getScope());
            proxyDefinition.setLazyInit(targetDefinition.isLazyInit());
            // set the target
            proxyDefinition.setDecoratedDefinition(targetHolder);
            proxyDefinition.getPropertyValues().add("target", targetHolder);
            // create the interceptor names list
            proxyDefinition.getPropertyValues().add("interceptorNames", new ManagedList<String>());
            // copy autowire settings from original bean definition.
            proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
            proxyDefinition.setPrimary(targetDefinition.isPrimary());
            if (targetDefinition instanceof AbstractBeanDefinition) {
                proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
            }
            // wrap it in a BeanDefinitionHolder with bean name
            result = new BeanDefinitionHolder(proxyDefinition, existingBeanName);
        }

        addInterceptorNameToList(interceptorName, result.getBeanDefinition());
        return result;
    }

带来在上述问题,本文尝试当智能时代的那个现象下,系统思维产品的转换与无转移,以及当产品人的我们,该怎么还定位,抢得智能红利?

1、吴军在智能时代里究竟讲了若干什么?

吴军于智能时代里总围绕在这样一个命题:“智能时代这次实在来了”。

人造智能是定义实际上于1956年达特茅斯学院之集会上就吃提出来,到2016年曾经历了60年一个甲子的时日。期间三从些许获取,第一不行是小鸟飞派也表示,以规则学习、专家系统为主,期望知道人脑来促进人工智能进展;不过大家为都亮,人类对大脑的接头微乎其微,人工智能技术陷入低谷。

其次不善是为作通信的贾里尼克也代表的统计学派,基于香农提出的信息论来缓解人工智能的题材。此时,各种智能问题其实为理解成消除无明了问题,这种想模式之升级的又管人工智能应用上推进同步。

骨子里,确定性思维(又如连续性思维)一直是工业时代之精髓,胡适老先生便提出过教育几替人之“大胆要,小心求证”,即“先借要一个冠型,然后又经过数据证明迭代构建一个错综复杂的模子”。无论是牛顿,还是爱因斯坦之做到其实都是基于上述思想构建的结晶。

若是显思维也越来越被挑战:一方面随着我们针对认知的加剧,影响这个世界的变量越来越多,另一方面,量子力学的测不准原理等还控制了社会风气不确定就同中心特征。在未来简史中,尤瓦尔·赫拉利从人类学、历史学等角度也阐述了类似的意见。他提出了文化之悖论,知识(预测)不移行为即便管用,行为一经改变,原本的知(预测)就随即去了意思。

人为智能虽然像在语音识别等题材达成,准确率得到大幅升级,但是由于数据量、计算能力相当于之限制,大部分运用仍回天乏术商用。

人造智能(神经网络)研究之老三不善浪潮开始为 2006
年的突破。借这浪潮,深度上(Deep Learning)概念(参见Ian
Goodfellow等,Deep Learning,P17)普及起来来。而标志性的代表尽管是,Hinton
和合伙人的舆论”A fast algorithm for deep belief nets”
(深信度网络的同等种高效算法)。下面虽然是深度上型示意图:

深上型示意图

趁互联网、大数量、并行计算等技巧之腾飞,尤其是不行数据的数据量大、多维度、完备性等风味加速人工智能的老三糟糕浪潮。

2016年,AlphaGo打败了李世石,围棋这个人类引以为傲的棋比赛型时曾经遥落后于机器智能;悄无声息间,google的无人驾驶汽车都行驶了超越200万英里。

AlphaGo打败李世石,一作战成名

起人类历次技术革命的开拓进取过程来拘禁,无论是第一不好的蒸汽机革命、第二不良的电力革命要第三不行的信革命,无不推动着既出家财的圆提升。

可预见人工智能将会见逐年渗透到社会之逐条产业,从而实现“从部分到总体,我们兑现智能化社会,从总体到有的,我们落实社会之精细化”的奇特场景。

二、ProxyFactoryBean的原理
咱们事先来拘禁一下ProxyFactoryBean的接轨关系:

自身尝试用同一句话来概括一下智能时代之见地:一栽采取信息(大数据被发掘)问题迎刃而解人工智能问题(不明了问题)的思考方法面世了,同时,新的生产力(人工智能和特别数目等)必会带新的生产关系(产业)的晋升。

2、智能时代下,下一波产品红利在乌?其驱动力到底是啊?

起互联网近20年的前进来拘禁,可以归结为老三独发展周期,每个周期接近7-8年左右的工夫,期间产生波峰的全速发展,也有波谷的泡沫散尽。郝志中在《用户力》里做出综合总结:

中国互联网发展轨道图

自打上图可以看到,三单周期大概如下:

1)第一个周期,1995年-2002年,窄带互联网,特征是三充分山头的发达,02年于,WEB1.0找到了商业模式。

2)第二独周期,2002年-2009年,宽带互联网,特征是情媒体很丰富,图文,视频等传媒相颇为流行,BAT完整对流量入口的布局,正式进入WEB2.0。

3)第三个周期,2009年-2016年,移动互联网,特征是微博、微信大行其道,而2015年之股市崩盘,预示着互联网企业的高估值神话破灭,死掉的O2O企业名单一批判对接一批,16年开回归理性,互联网+开始逐渐渗透及各行各业。

要是上述的周期的改变,其底层逻辑可以据此如下基本原理(公式)所论述:

公式1:信息传播之速率不可能过信道的容量(信息论的老二定律)

公式1得以简简单单明了吧,窄带互联网,宽带互联网,移动互联网作为基础信道决定了上层的消息传播之相(产品的貌)。现在,巨头们都在豪赌AR、VR会继智能手机外,成为另外一个根基础信道。(后面会波及)

这就是说新的艺导致生产关系变化之法则而是如何的啊?产品形态有安具体的差?咱们就看(大胡子等丁总):

不同周期的出品形象

起地方这张图可以看到,横轴(1)代表的是出于底层技术使之老三老出品周期,分别是窄带互联网及宽带互联网,再届移动互联网。而纵轴(2)代表的是某某大产品周期下之产品类别,规律突显,总起这么的产品类别:

1)为用户提供消息服务为主底活

2)为用户提供娱乐(游戏)为主的成品

3)为用户提供交流(社交、社区)为主的活

4)为用户提供服务(衣食住行首当其冲,并会于外行业逐步渗透)为主底活

扣押明白过去,就足以预计未来。

那么,驱动下一波的活周期的最底层信道会是何许人也?

AR?VR?从Facebook重金收购Oculus看,他们解注VR;而自Google不断重开失败多次的Google
Glass项目与微软力推HoloLens项目看,他们押送注AR。而于AR、VR的其实经验和采取来拘禁,目前尚没成功其整体产品之构建(还处于摩尔所讲述的线当中)。

而其他一样种植更加大家所接受之见则是互联网+,即祭互联网、大数据、云计算等消息技术去改善传统行业的值结构,压缩资产,提高效率。

润米咨询创始人刘润已提出了产业+互联网的价值公式:“始建价值 +
传递价值 =
用户价值
”。企业根据价值定位不同足以分为因创建价值为中心(产品型公司)的和坐传递价值吧核心(渠道型和营销型公司)的有限种不同品种的店家:

供销社不同的价值定位

据苹果、特斯拉、微信就属于产品型公司,而耐克,李宁,加多宝,农夫山泉则重复多的属渠道型或营销型公司。

刘润说了一个颇厚的理念:“本条世界之上扬是由少道力量以推进着,一个凡是真正的换代,一个凡最最的频率,价格上升是创新红利,价格下降是效率红利,真正的换代反是世界,并被创新者享受创新所带来的红,而最为的频率由此降低价格再把这红利返还深受全社会,两股力量如此往返,推动社会风气上向上。”

整套互联网的迈入,即信息革命的底逻辑可以理解成下面是基本原理(公式):

公式2:新技巧+现有产业=新产业(所谓的新的技能导致生产关系的变化)

公式2得大概明了呢,随着互联网根的技巧,包括网络带来富,智能手机,芯片计算能力相当于技能驱动之上次产业要产品形象的扭转。

故此,我们可清楚也,互联网的上半场就错过,即所谓的互联网将最外面的货色的都召开了一致全副。若是互联网的下半场则重新或者是故重新强有力的最底层技术以及生产力,把全华所有的货都再度开同样满。**

免早呢无晚,在十分数量、摩尔定律以及更进步的算法驱动下之人为智能则会又加速技术让之换代以及效率的升官。

3、智能时代以诞生一种植更高维的制品模式

极关键之活合计模式层面,也会见发巨大的变迁。现在那个流行的精益创业的主干考虑方式实在是因假设不断证明迭代的过程。

具体地,可以扣押下面就张图,我们由此(1)基于同理心洞察的创新使得,找到我们觉得的一些用户痛点或更新的机会点,再经过(2)基于价值如的精益创业来持续交付、验证和调整。

精益创业之活模式

旋即是我们现最好盛的均等栽产品启动和活迭代的方法,而周过程看似下面这张图:

精益创业模式下之活迭代的路线图

故此会连的调产品迭代路线图,是为咱们的创业与创新处在极端不确定受,大家只能不停的比方,验证,再使。在是进程遭到我们不得不于谁验证的血本再不比,验证的进度又快,即所谓的“Fail
Cheap,Fail Fast”。这几是同样仿事实上的产品合计。

设当人工智能时代下,在产品目标的驱动下,我们于一些场景下,可能不必再去如了。而是径直通过构建与采取多维度,完备的异常数额来去解决中的不确定性问题(假设),再经过机器识别,直接得到模式(需求相和行业洞察)直接去化解行业问题。

借想,你还当迷雾中航海,你只有通过不断使以及说明去摸到对岸方向的时刻,别人则利用好数目与人造智能精准的制导,直接找到了解决问题的模式。哪个还快?哪个效率高?

就算吓于脚的经文案例,传统1.0之模式,不考虑用户的需,直接做出一个蛋糕,结果发现无是用户需要之;而至了2.0之精益创业模式,为了证明用户之需求,我们利用MVP的艺术,不断证明和调整我们的MVP,最终做出用户喜爱之蛋糕;而到了3.0杀数据的模式识别模式,我们来或因大数据的多维度、完备性等特征一直获得一个再速,用户还热衷的蛋糕。

差一点种产品模式的距离

假如于智能时代,谁掌握了第三种产品合计模式或者会见对亚栽及率先种植变异降维攻击和碾压。而左右第三种植产品合计模式的重中之重,可能未是优先关注“我观察到了呀用户痛点或行业痛点”,而是先考虑“看看我们掌握了聊数量,还亟需什么数据,有了这些数量我们能干哪事。”

再度向生推进想去,可能是这样同样种植常见,在人情行业里,谁首先于以业数据先流动起来,优先形成闭环并重构行业效率,谁就是拿下了新的制高点。正使吴军所说:“谁掌握了音信,谁就可知获取财富,就犹如在工业时代,谁掌握了基金谁就是可知取财富一样。”

活之商业模式将为获取数据为重点目的,为了多少可大大方方用到免费政策。而休光要获取数据,还要想在提供再多的数码连接和置换。这样,无疑会并发一个壮烈的正反馈,拥有更加多多少的庄,可以换成得更多多少,得到重新多数据,也就是有了再次多之音讯以及财。至此,会并发大量的行当数据(或一些领域数据)的大人物,甚至是超越行业的数量巨头,他们会颠覆BAT,会成下一个BAT。

此外,讲真,产品之内涵其实为犯愁发生了转,原先的活内涵是:“为人口供劳务要价值”,而今日人数成为了人数及机器人,或是像未来简史里面所勾画的:生物只是算法,生命只是算法的处理。那还要会是一样幅怎样的景?

4、产品人需要关爱如何新的浮动?

以面前所提及的老三种植产品合计模式(智能时代下必备的沉思模式)下,会并发如下产品数量流程:

智能时代下的产品数量流程

咱们得望对于不同之劳动对象(2C、2B),产品及会展现不同的新特征:

对此2C类(面向消费者市场)的活,用户各维度的表现数据还见面给平台所募,借由机器上的算法,产品会主人口千面:在不同的场合,不同之空间和时间里,你得的制品服务是勿平等的。同一时空下,两个人拿走服务呢是匪雷同的。产品会更为个性化和场景化。事实上,无论是亚马逊,Netfix(网飞),还是今天头条都曾经于这条路上了,并透过此法构建了该出品基本竞争力。所以今日条长条其实不是一模一样寒传媒公司,它是如出一辙家数算法公司。

对于2B类(面向企业服务市场)的活,效率还会是一个最关切的严重性词。卫哲以混沌研习社中开过一样次于“提升效率”为主题的分享,其中包括:个人效率、组织效率、资产效率、战略效率、创新效率五单非常板块。

于这的逐渐饱和和为透支的主顾市场来拘禁,面向企业服务市场之频率提升会是一个重中之重机会点。而绕这个进行的,有点儿只地方:一方面大量底XAAS公司来作底层支撑去提升公司的各国维度效率,另一方面,来自行业外的店,会生有人口率先站出来,构建行业数据的全流程采集,以及数解析处理的闭环,并尝试采用通过杀数据的点子去观察一些行痛点和机会点。

事实上B类产品跟C类制品都绕不上马效率,举个例子,时下最火的共享经济就那本来面目就是效率,更纯粹的说是追资产利用率。

以对于摩拜单车、OFO的模式主要不在于有微辆车,而是每部车每天的使用率。如果车之使用率没有,那就是一个效率低之小卖部。

还坐共享单车为例,我们已经不再购买商品(自行车),我们买服务,商品是按照计划生产出来的,有些许用户我们是一心明了的,有略用户用了车子我们吧是明的。如果世界之自行车还是共享单车的话,我们就知晓世界微人口用、还亟需多少辆自行车。而这种模式极其有话语权的既无是单车的厂家,也未是顾客,而是中间的阳台调度公司,即杀数额算法公司。

不怕如未来简史里面涉及的,算法会成为像公司同国家这样的实业,掌握人类。

当未来IoT+机器智能为共享经济带动了或者。在共享经济中,连接比有所(内容)更要。Google、Facebook没有内容,阿里莫商品,微信没有网络,滴滴,uber、AirBnB没有车以及房子。

如今剧变之共享经济(AirBnB、滴滴、共享单车、共享充电等)只是人为智能大展拳脚的一个市面切入点。

或,真的要吴军在智能时代中所说,从有到整体,我们贯彻智能化社会,从整体到有的,我们实现的社会之精细化。

5、智能时代会涌现哪些产品会?

智能时代下的活服务类型大致会发这样的组成:

智能时代下之成品服务型

首先栽的产品服务类型,提供包括自数收集、数据解析处理、机器上等基础技术能力的产品服务。比如,像Google、Facebook、baidu等。

第二种植产品服务类型,则是眼前提到的,行业内的店铺温馨构建以业还是过行业的多寡搜集、分析、处理的闭环。成为该行业数据服务以及信息服务的要害结点。在马上点及,面向消费者,面向企业或许面向政府之动本质上差异不老。

及时意味着,传统行业立足行业之依,依然大有可为。而且也跟互联网+的大潮十分适合。

除此之外前方两良海量市场外,绝大部分面向终端服务的成品门类会是何许一种植现象为?

实质上,早在20年前,哈佛经贸评论(HBR,1998)就关乎了经验经济之趋向及其价值模型,并涉嫌:产品之心得更加好,越闹差异性,就越来越会赢得重新强之价值就同发展趋势。

经济腾飞之值模型

实则这个原理一直从未换,且我们还有为数不少东西而举行。

于2016年的哈佛生意评论(HBR.ORG
2016.9)中涉嫌产品的需要金字塔型(见下),在该模型中,产品之求自下而上分为,功能,情感,自我实现以及社会影响力等。总体的大方向是,如果会盖至进一步强的层系,用户的忠诚度更强,产品的值敏感性也进一步强。

产品要求金字塔型

单单创新,才生两样,唯有不同,才起高利。

我都当《产品拆解:透析网易云音乐背后的造物逻辑》惨遭提到网易云音乐能以非至4年的流年发展3亿用户,能以BAT的布局之音乐红海市场饱受颇出同长达血路,能成中华极其有口碑的乐产品的中心在于其构建了同效仿有诗意交互的体会框架。曾经也不绝于耳一位有点伙伴告诉我,网易云音乐是那唯一愿意付费的乐产品。事实证明,其为在4月初将到A轮融资,估值80亿。

网易云音乐的核心体验框架:具有诗意的互

理所当然,机器人最终也会有所情感。

唐纳德·A·诺曼在《情感化设计》中干,机器也最终会有感情,虽然机器的真情实意与人的结不平等,但是咱得机械发出理解主人情感状态的力。同时机器具备积极的情感会不断的精益求精,而具消极的情义则足以当的保安好。甚至是挫败感和自豪感都可拉更好地完成任务(情感化设计,P176)。不过离就同一上至少还有挺丰富的一段距离。

6、小结:未来早已来,我们准备好了吗?

正文回顾了吴军智能时代下的千奇百怪场景,并尝试通过个别独关键性原理(First
Principle),即信息论第二定律以及底层技术(生产力)决定上层生产关系,来眺望互联网浪潮的下一波红利,及其真实性的底层驱动力。

双重进一步地,本文着重分析了智能时代下用出生一栽更加高纬度的制品合计模式,其创新性和频率远超时下最盛行的精益创业的盘算模式。

这种高纬度的出品合计模式将助长所有2C以及2B产品形象的升级,2C之活的竞争力在数量洞察后底总丁千面,更加个性化与场景化;而2B的成品竞争力在体现数据闭环所提升的效率。愈演愈烈的共享经济(共享单车等)则是这种思想模式以及活形象的一个缩影。

吴军说,那么成为那么2%,那么尽管于淘汰。而本文则觉得,显然会与挑战现有,尤其对于传统行业,谁先构建数据闭环,优先成为该行业数据服务以及信息服务之根本结点,谁就是发生或于按照业抢占先机。

自然感受经济仍然是值得大家关注同突破的领域,做好极端体验,你晤面吃你的活由价格敏感提升为价值敏感。

丹尼尔·平克以《全新思维》中,他敏锐地觉察到,人类社会既步入“右脑时代”,在是时代,知识不再是力。他开创性地指出:未来属那些拥有与众不同思维的人口,唯有拥有右脑时代之6充分新思维能力:设计感、娱乐感、意义感、故事力、交响力、共情力,即“三感三力”,才会为决胜于未来。

好预计至,产品经营会至少分化成稀种植角色,数据产品经营或算法产品经理可能是如出一辙近似崛起的职,他们又讲求左脑思维,也会见跟目前的一部分支付岗位形成万众一心。超过6员数年薪之多少科学家可见一斑。

而原本的产品经理,可能再次多的偏袒社会学,心理学,设计学等多学科综合的职务,他们再次强调右脑思维。

享誉未来学家彼得•伊利亚德说:“今天我们而非生于未来,那么未来我们拿生于过去。”

前途早就来,你见面怎么挑为?或许在数据以及算法面前,我们早就困难。

往期精彩文章

活拆解:透析网易云音乐背后的造物逻辑

计划思想:这说不定是国内高校最早的制品经理课程

计划思想:拆产品或是建完全产品观之尽抢实践了,但您恐怕拆的凡假产品

ProxyFactoryBean类图

ProxyFactoryBean实现了FactoryBean、BeanClassLoaderAware、BeanFactoryAware接口,这里就是无多说了。ProxyCreatorSupport这个近乎则是开创代理对象的关键所在。  我们先行来探有代理对象的方式:

public Object getObject() throws BeansException {
        initializeAdvisorChain();
        if (isSingleton()) {
                        //单例
            return getSingletonInstance();
        }
        else {
            if (this.targetName == null) {
                logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +

                        "Enable prototype proxies by setting the 'targetName' property.");
            }
                        //非单例
            return newPrototypeInstance();
        }
    }

initializeAdvisorChain()
方法是以通告链实例化。然后判断目标是否要生成单例而选择调用不同的计,这里我们只看生成单例对象的不二法门。

private synchronized Object getSingletonInstance() {
        if (this.singletonInstance == null) {
            this.targetSource = freshTargetSource();
                        //如果以接口的方式代理对象
            if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
                // Rely on AOP infrastructure to tell us what interfaces to proxy.
                Class<?> targetClass = getTargetClass();
                if (targetClass == null) {
                    throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
                }
                      //获取目标类实现的所有接口,并注册给父类的interfaces属性,为jdk动态代理做准备
                setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
            }
            // Initialize the shared singleton instance.
            super.setFrozen(this.freezeProxy);
                   //这里产生代理对象
            this.singletonInstance = getProxy(createAopProxy());
        }
        return this.singletonInstance;
    }

咱得以看到,产生代理对象是透过getProxy()方法实现的,这个点子我们看一下:

protected Object getProxy(AopProxy aopProxy) {
        return aopProxy.getProxy(this.proxyClassLoader);
    }

AopProxy对象的getProxy()方法有我们用的代办对象,究竟AopProxy这个看似是啊,我们接下去先押一下生这个目标的法子createAopProxy():

protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            activate();
        }
        return getAopProxyFactory().createAopProxy(this);
    }

createAopProxy方法:
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
                //目标对象不是接口类的实现或者没有提供代理接口
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }  
            //代理对象自身是接口
            if (targetClass.isInterface()) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

每当此处我们一味看JdkDynamicAopProxy这个看似的落实,我们前提到,真正代理对象的浮动是出于AopProxy的getProxy方法成功的,这里我们看一下JdkDynamicAopProxy的getProxy方法,这吗是本文讨论的机要:

public Object getProxy(ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
        }
        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

咱俩看可以非常了解的看来,代理对象的成形直接采用了jdk动态代理:Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);假如代理逻辑是透过落实了InvocationHandler接口的invoke方法实现之。而此以的兑现了InvocationHandler接口的类就是JdkDynamicAopProxy自身。JdkDynamicAopProxy自身实现了InvocationHandler接口,完成了Spring
AOP拦截器链拦截等一样文山会海逻辑,我们看一下JdkDynamicAopProxy的invoke方法的具体贯彻:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        MethodInvocation invocation;
        Object oldProxy = null;
        boolean setProxyContext = false;

        TargetSource targetSource = this.advised.targetSource;
        Class<?> targetClass = null;
        Object target = null;

        try {
            //没有重写equals方法
            if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
                // The target does not implement the equals(Object) method itself.
                return equals(args[0]);
            }
            //没有重写hashCode方法
            if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                // The target does not implement the hashCode() method itself.
                return hashCode();
            }
          //代理的类是Advised,这里直接执行,不做任何代理
            if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
                    method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                // Service invocations on ProxyConfig with the proxy config...
                return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
            }

            Object retVal;

            if (this.advised.exposeProxy) {
                // Make invocation available if necessary.
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }

            // May be null. Get as late as possible to minimize the time we "own" the target,
            // in case it comes from a pool.
            //获得代理对象
            target = targetSource.getTarget();
            if (target != null) {
                targetClass = target.getClass();
            }

            // Get the interception chain for this method.
            //获得已经定义的拦截器链
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

            // Check whether we have any advice. If we don't, we can fallback on direct
            // reflective invocation of the target, and avoid creating a MethodInvocation.
            if (chain.isEmpty()) {
                // We can skip creating a MethodInvocation: just invoke the target directly
                // Note that the final invoker must be an InvokerInterceptor so we know it does
                // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
                //拦截器链是空的,直接执行需要代理的方法
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
            }
            else {
                // We need to create a method invocation...
                //这里是调用拦截器链的地方,先创建一个MethodInvocation对象,然后调用该对象的proceed方法完成拦截器链调用
                invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                // Proceed to the joinpoint through the interceptor chain.
                retVal = invocation.proceed();
            }

            // Massage return value if necessary.
            Class<?> returnType = method.getReturnType();
            //这里处理返回值,判断返回值和方法需要的返回是否一致
            if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
                    !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                // Special case: it returned "this" and the return type of the method
                // is type-compatible. Note that we can't help if the target sets
                // a reference to itself in another returned object.
                retVal = proxy;
            } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
                throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
            }
            return retVal;
        }
        finally {
            if (target != null && !targetSource.isStatic()) {
                // Must have come from TargetSource.
                targetSource.releaseTarget(target);
            }
            if (setProxyContext) {
                // Restore old proxy.
                AopContext.setCurrentProxy(oldProxy);
            }
        }
    }

拦器链的调用

自打点的代码和注释中我们得望spring实现aop的基本点流程,具体什么调用拦截器链,我们来拘禁一下MethodInvocation的proceed方法

public Object proceed() throws Throwable {
        //  We start with an index of -1 and increment early.
        //   currentInterceptorIndex是从-1开始的,所以拦截器链调用结束的时候index是 this.interceptorsAndDynamicMethodMatchers.size() - 1
        //  调用链结束后执行目标方法
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }
        //  获得当前处理到的拦截器
        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        //  这里判断是否是InterceptorAndDynamicMethodMatcher,如果是,这要判断是否匹配methodMatcher,不匹配则此拦截器不生效
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            // Evaluate dynamic method matcher here: static part will already have
            // been evaluated and found to match.
            InterceptorAndDynamicMethodMatcher dm =
                    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
                return dm.interceptor.invoke(this);
            }
            else {
                // Dynamic matching failed.
                // Skip this interceptor and invoke the next in the chain.
                return proceed();
            }
        }
        else {
            // It's an interceptor, so we just invoke it: The pointcut will have
            // been evaluated statically before this object was constructed.
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }

proceed()方法是一个递归方法,我们得以根据代码的注释知道大致逻辑,InterceptorAndDynamicMethodMatcher的代码如下,我们得以望,InterceptorAndDynamicMethodMatcher
持有一个MethodInterceptor 对象及一个MethodMatcher
对象,在阻碍器链调用过程被,如果拦截器是InterceptorAndDynamicMethodMatcher
,则会事先冲MethodMatcher 判断是否配合,匹配MethodInterceptor 才见面收效。

class InterceptorAndDynamicMethodMatcher {

    final MethodInterceptor interceptor;

    final MethodMatcher methodMatcher;

    public InterceptorAndDynamicMethodMatcher(MethodInterceptor interceptor, MethodMatcher methodMatcher) {
        this.interceptor = interceptor;
        this.methodMatcher = methodMatcher;
    }

}

关于MethodInterceptor 是啊,MethodInterceptor
的逻辑是安的,我们得以关押一下MethodInterceptor
的一个子类AfterReturningAdviceInterceptor的落实:

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {    private final AfterReturningAdvice advice;    /**     * Create a new AfterReturningAdviceInterceptor for the given advice.     * @param advice the AfterReturningAdvice to wrap     */    public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {        Assert.notNull(advice, "Advice must not be null");        this.advice = advice;    }    @Override    public Object invoke(MethodInvocation mi) throws Throwable {        Object retVal = mi.proceed();        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());        return retVal;    }}

AfterReturningAdviceInterceptor的打算是以为代理的方返回结果随后续加我们用的拍卖逻辑,其落实方式我们得以看到,先调用MethodInvocation
的proceed,也即是优先连续处理拦截器链,等调用完成后行我们需要的逻辑:this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
暨此,spring使用jdk动态代理实现aop的分析多结束,其中拦截器链的调用比较难了解而且于重大,需要的同班可以基本上看看就等同块。
当程序员这长达路上碰到瓶颈的情人可加入过多:654675708 大家并来提升发展
但要备注好信息 注!
有Java高级大牛直播讲解知识点,分享文化,有五良专题都是各位老师多年办事更的梳理与小结,带在大家到、科学地起和谐的艺系统和技能认知
等级同:工程化技术-提升效率 才能够发出双重多之时光来琢磨

品二:源码分析-成为一个内功深厚的程序员

路三:高性能 分布式 高可用-进入互联网商家不再是若的难题

品四:性能调优-我不愿只开一个程序员 我还有再胜的姣好

等五:项目实战-理论以及时执行互相结合 你距离梦想的去仅学而而点由脚尖