ioc 订阅
国际奥林匹克委员会,简称为国际奥委会,是一个国际性的、非政府的、非赢利的组织。是奥林匹克运动的领导机构,它于1981年9月17日得到瑞士联邦议会的承认,确认其为无限期存在的具有法人资格的国际机构。总部位于瑞士洛桑。由法国人皮埃尔·德·顾拜旦建立,首任主席是泽麦特里乌斯·维凯拉斯。据2017年01月16日《人民日报》(海外版)第06版介绍,国际奥委会有100个委员和32个荣誉委员。 [1]  1894年6月23日,国际奥委会在巴黎召开的国际体育代表大会上成立,发起人是法国的教育家皮埃尔·德·顾拜旦男爵。成立之初总部设在巴黎,1914年第一次世界大战爆发,为避战火,1915年4月10日迁入有“国际文化城”之称的瑞士洛桑。国际奥委会根据现代奥林匹克运动创始人顾拜旦的理想,恢复奥林匹克运动的目的,在于增强各国运动员之间的友谊与团结,促进世界和平以及各国人民之间的相互了解,发展世界体育运动。《奥林匹克宪章》明文规定,国际奥委会的宗旨是:鼓励组织和发展体育运动和组织竞赛;在奥林匹克理想指导下,鼓舞和领导体育运动,从而促进和加强各国运动员之间的友谊。国际奥委会组织举办奥林匹克运动会、青年奥林匹克运动会、冬季奥林匹克运动会、残疾人奥林匹克运动会。它组织的首届夏季奥运会于1896年于希腊雅典举行,首届冬奥会于1924年在法国霞慕尼举行。在2018世界品牌500强排行榜中,国际奥林匹克委员会排名第125位。 [2] 展开全文
国际奥林匹克委员会,简称为国际奥委会,是一个国际性的、非政府的、非赢利的组织。是奥林匹克运动的领导机构,它于1981年9月17日得到瑞士联邦议会的承认,确认其为无限期存在的具有法人资格的国际机构。总部位于瑞士洛桑。由法国人皮埃尔·德·顾拜旦建立,首任主席是泽麦特里乌斯·维凯拉斯。据2017年01月16日《人民日报》(海外版)第06版介绍,国际奥委会有100个委员和32个荣誉委员。 [1]  1894年6月23日,国际奥委会在巴黎召开的国际体育代表大会上成立,发起人是法国的教育家皮埃尔·德·顾拜旦男爵。成立之初总部设在巴黎,1914年第一次世界大战爆发,为避战火,1915年4月10日迁入有“国际文化城”之称的瑞士洛桑。国际奥委会根据现代奥林匹克运动创始人顾拜旦的理想,恢复奥林匹克运动的目的,在于增强各国运动员之间的友谊与团结,促进世界和平以及各国人民之间的相互了解,发展世界体育运动。《奥林匹克宪章》明文规定,国际奥委会的宗旨是:鼓励组织和发展体育运动和组织竞赛;在奥林匹克理想指导下,鼓舞和领导体育运动,从而促进和加强各国运动员之间的友谊。国际奥委会组织举办奥林匹克运动会、青年奥林匹克运动会、冬季奥林匹克运动会、残疾人奥林匹克运动会。它组织的首届夏季奥运会于1896年于希腊雅典举行,首届冬奥会于1924年在法国霞慕尼举行。在2018世界品牌500强排行榜中,国际奥林匹克委员会排名第125位。 [2]
信息
创建者
皮埃尔·德·顾拜旦(法国人)
外文名
International Olympic Committee(英),Comité international olympique (法)
简    称
国际奥委会(IOC)
成    员
206国家和地区
总    部
瑞士洛桑(Lausanne)
中文名
国际奥林匹克委员会
官    网
http://www.olympic.org/
成立时间
1894年6月23日
现任主席
托马斯·巴赫
官方语言
英语、法语
国际奥林匹克委员会发展历程
1894年6月16日-24日,根据世界著名的国际体育活动家,法国人皮埃尔·德·顾拜旦的建议,来自法国、英国、希腊、瑞典、意大利、俄国(俄罗斯)、比利时、捷克斯洛伐克、新西兰、美国、阿根廷、匈牙利12个国家的49个体育组织的代表,在巴黎索邦神学院举行国际体育运动代表大会。在开幕式上,法国著名古希腊文化专家切奥多尔·莱拉赫发表演说,巴黎国家歌剧院合唱团为大会演唱了阿波罗颂歌,唤起了与会者对古奥运会的神往。 [3]  会议期间,又先后有21个国家致函,向大会表示支持和祝贺。这次会议通过了成立国际奥委会(成立时间1894年6月23日,成立时的名称是“奥林匹克运动会国际委员会”)的决议,并从79名正式代表中选出15人任第1届国际奥委会委员。大会还决定由奥运会举办国的国际奥委会委员担任国际奥委会主席。由于首届奥运会定于1896年在希腊首都雅典举行,因此希腊委员泽麦特里乌斯·维凯拉斯当选国际奥委会第一任主席,顾拜旦为秘书长。会议规定法语(现为英、法两种语言)为国际奥委会法定语言。大会还决定沿袭古奥运会传统,每四年举行一次运动会,还规定奥运会的比赛项目为田径、水上运动(包括帆船、划船、游泳)、击剑、摔跤、拳击、马术、射击、体操、球类运动等。第一届奥运会原定于1900年于巴黎举行,后来考虑希腊为古代奥运会发源地,在希腊举行比在巴黎意义更重大些,顾拜旦尊重了大家的意见。大会决定把第一届会期改在1896年,鉴于古代奥运会遗址奥林匹亚已成了一片废墟,会址改设在希腊首都雅典。奥运会最早始于古希腊的奥林匹亚由古代希腊人民为祭神和崇拜英雄而举行的一些竞赛活动逐渐发展形成的。举行的地点就在古希腊雅典城西南方向360公里外的奥林匹亚村举行,因此而得名。第一届古代奥运会于公元前776年举行,共举行过293次。后来罗马帝国的入侵古希腊后,由于罗马皇帝狄奥多西信奉基督教,禁止一切关于异教的活动,因此运动会在公元393年被罗马皇帝狄奥多西废除。 [1]  1889年,法国的顾拜旦男爵提出恢复奥林匹克运动的建议。第一届近代奥运会于1896年在希腊举行。以后每四年举行一次。即使其间因故不能举行,届数仍然依次照算(第6、12、13届未举行。第6届由于第一次世界大战的爆发未能举行,第12,13届则因为第二次世界大战的爆发未能举行)。至2016年,已经举行过31次奥运会,最近的一次是在巴西的里约热内卢举行的奥运会。1897年一家法文报纸首次称之为“国际奥林匹克委员会”,1901年正式改用现名。1914年第一次世界大战爆发,为避免战火洗劫,1915年4月10日总部从巴黎迁到瑞士洛桑。早在1922年,中国奥委会就得到了国际奥委会的承认。 [4]  中国曾派运动员参加了1932年、1936年和1948年的三次奥运会。新中国首次派队参加了1952年在赫尔辛基的第15届奥运会。但不久,当时的时任国际奥委会主席布伦戴奇把台湾列入了国际奥委会所承认的各国奥委会名单之中,企图制造“两个中国”。中国多次抗议交涉无效,于1958年声明中断与国际奥委会的关系。从1946年起,国际奥委会执委会分别与冬、夏季国际单项体育联合会之间不定期举行联席会议;从1952年起,国际奥委会执委会与国家奥委会之间也不定期举行联席会议。1975年,中国奥委会要求国际奥委会恢复在奥林匹克运动中的合法代表权。1979年10月,国际奥委会通过《名古屋决议》,恢复了中国奥委会在国际奥委会的权利,确认中国为“中国奥委会”,使用中华人民共和国国旗和国歌;同时规定设在台北的奥委会为“中华台北奥委会”,使用“不同于其使用的旗、徽和歌”。会址设在台北的奥委会改名为“CHINESE TAIPEI OLYMPIC COMMITTEE”。大陆方面自此将“CHINESE TAIPEI”翻译为“中国台北”。何振梁于1981年和1985年当选为国际奥委会委员和执委会委员。1985年,国际奥委会启动奥林匹克全球伙伴计划(TOP计划),四年一期,实施TOP营销计划实施以来,这项收入不断攀升,并逼近电视转播权收入。1986年,国际奥委会授予中国奥委会奥林匹克杯,以表彰中国对发展中国家,特别是对非洲国家体育援助作出的巨大贡献。1989年8月,何振梁当选为国际奥委会副主席,这是中国人首次担任这个职务。 [5]  1993年,中国奥委会曾向国际奥委会提出了北京举办2000年奥运会的申请,但最后以2票之差而落选。1993年6月20日,国际奥委会执委会决定暂时承认马其顿为其成员。同年9月,巴勒斯坦被接受为临时委员。1993年9月,布隆迪、佛得角、科摩罗群岛、圣多美和普林西比、多米尼加等被接纳为新成员。1994年6月,瑙鲁加入国际奥委会。1994年8月29日至9月3日,第12届奥林匹克代表大会在巴黎召开,它也是现代奥林匹克运动恢复100周年的庆祝活动的一部分。参加本届大会的代表共有3427人,其中:国际奥委会委员和名誉委员101人;来自 48个国际单项体联的代表132人;来自191个国家或地区奥委会的代表407人;运动员代表67人;记者代表738人。在大会上发言的共达439人次。1995年7月,柬埔寨、几内亚比绍加入国际奥委会。1996年,国际奥委会与联合国粮农组织(FAO)签署了合作协议,双方愿采取积极具体措施为全球农村地区的人口谋取福利。国际奥委会与奔驰汽车公司就在6个非洲国家体育发展签订了一项耗资600万马克的“非洲奥林匹克计划”。1997年和1998年间,国际奥委会曾通过中国奥委会的协助,两次向朝鲜民主主义人民共和国体育界提供了食品援助。另外,国际奥委会还向巴塞罗那市签署合同,帮助重建萨拉热窝的扎特拉体育设施。1997年3月5日,国际奥委会同美国广播公司(NBC)签署了价值23亿美元电视转播权合同。根据协议,国际奥委会授予NBC在美国境内转播2004年奥运会、2006年冬奥会和2008年奥运会的权利,5月,国际奥委会和悉尼奥运会组委会共同与欧洲广播公司(EBU)签署了价值3.5亿美元的合同。另外,国际奥委会还制定了一项“奥林匹克计划”(TDP),利用五环标志和各国奥委会的会徽和名称进行市场销售。这一计划的实施,使得各国奥委会、尤其是发展中国家奥委会均能从中受益。 [6]  1997年7月3日,国际奥委会主席萨马兰奇宣布香港将以"中国香港"的名义参加奥运会。1998年12月,帕劳、厄立特里亚加入国际奥委会。1999年1月6日,中国奥委会全会在北京召开,决定由北京再次代表中国申办2008年第29届奥运会。1999年2月,国际奥委会在洛桑召开了世界反兴奋剂大会。大会通过了《洛桑宣言》,决定成立一个世界性的、独立的世界反兴奋剂组织(WADA)。国际奥委会承诺向该机构提供2500万美元的资金。1999年10月,在雅典召开的国际奥委会执委会决定:每四年在奥运会的发祥地举办一届世界青年节。2000年3月6日,国际奥委会在巴黎授予中国女子足球队“妇女和体育奖”。2001年7月,在第112届国际奥委会全会上,北京赢得了2008年奥运会主办权。在国际奥委会的倡议之下,2001年第56届联合国代表大会通过了一项由世界上170多个国家提出的题为“通过体育和奥林匹克理想来建立一个和平和更加美好的世界”的决议,呼吁在2002年盐湖城冬季奥运会期间实现“奥林匹克休战”。2003年7月,第115届国际奥委会全会于在布拉格召开,经过两轮投票,温哥华最后以56票胜出成为2010年第21届冬季奥运会举办城市。2004年,印度尼西亚的国际奥委会委员哈桑因涉嫌在一起建设工程中进行非法活动被判刑。同年8月他被赶出了国际奥委会。2005年,前国际奥委会副主席、韩国人金云龙被迫辞职。起因是他已经由于涉嫌韩国的体育-金钱腐败案件而被停职。为了避免被奥委会驱逐他不得不选择辞职。2004年,保加利亚国际奥委会委员伊万·斯拉夫科夫涉嫌腐败活动,被赶出了国际奥委会。2005年12月,国际奥委会委员,法国前体育部长和1976年蒙特利尔奥运会110米栏金牌得主德鲁特因为腐败案件被停职。 [7]  2006年15日,韩国籍国际奥委会委员朴永圣因为涉嫌挪用公款,已经被暂时剥夺了委员资格。国际奥委会在一份声明中说,在国际奥委会道德委员会对朴永圣调查期间,朴永圣“一切与国际奥委会委员资格有关的权利都将被暂时剥夺”。2011年7月8日,鉴于荷属安的列斯群岛已于2010年10月10日正式解散,国际奥委会第123次全会据此取消荷属安的列斯群岛的国家奥委会资格,同时批准了一系列相应措施,以尽可能保护该国运动员的利益,尤其是参与2012年伦敦奥运会的相关权益。 [8]  2013年9月9日,国际奥委会第125次全会在阿根廷首都布宜诺斯艾利斯投票选出了新一任的国际奥委会主席。最终来自德国的托马斯·巴赫从6名候选人中胜出,成为第九任国际奥委会主席,任期8年。上一任主席雅克·罗格退休。同时经过两轮投票,东京获得2020年夏季奥运会主办权。这是东京在1964年首次举办夏季奥运会后再获举办权。 [9]  2013年12月7日,国际奥委会主席巴赫表示,如果印度不能遵守奥林匹克反腐败规定将面临被开除会籍的下场。 [10]  2014年5月9日,国际奥委会发布公告,美国全国广播公司(NBC)与其签署了一份价值75亿美元的协议,获得了从2021到2032年间奥运会的独家转播权。协议还要求,NBC需另外支付1亿美元,用于2015至2020年间多项体育运动的推广。进入21世纪,NBC便一直独享奥运会转播权,其在2011年签署的一份文件就以44亿美元取得了从2014到2020年间历届奥运会的转播权。 [11]  2015年12月,国国际奥委会在官方网站正式宣布了反腐监督热线——这在历史上是前所未有的。决定将从2016年开始,对各国际体育组织实施财政和管理审计,审计将在第三方独立组织的主持下进行,包括国际奥委会和奥林匹克运动会组织委员会也包括在内。 [12]  2014年12月8日,在摩纳哥国际奥委会第127次全会表决了这一名为《奥林匹克2020议程》的改革提案,获全票通过(104名国际奥委会委员96人与会、8人缺席)。国际奥委会的奥运改革拉开序幕。全会同时投票,正式接纳科索沃奥委会成为其成员。 [13]  新的申办体系下,国际奥委会将变“申办”为“邀请”,申办城市可于邀请阶段与国际奥委会进行探讨,并需将承办奥运会融入其自身的发展规划中,而不是反向为之,国际奥委会甚至允许跨城、跨境联合申办,只不过巴赫称那须得是“特殊情况下的特事特办”。在新的奥运设项规则下,国际奥委会变大项基础制为小项基础制,不再将设项局限于28个大项,而是通过规定运动员、官员和小项的总数上限来实现规模控制,其中夏季奥运会的“帽”是10500名运动员、310个小项,冬奥会则为2900名运动员和100个小项。东道主将在增项议题上拥有更多主动权。 [14-15]  2015年7月31日,国际奥委会第128次全会在吉隆坡举行,经过85位国际奥委会委员的投票,国际奥委会主席巴赫宣布,北京获得2022年冬季奥运会举办权。北京成为首个同时主办夏季奥运会和冬季奥运会的城市,瑞士西南部城市洛桑则获得了2020年青冬奥会的举办权。 [16]  2015年8月2日,通过由国际奥委会所有协会成员参与的投票决定,南苏丹得到国际奥委会的最终认可,成为奥林匹克大家庭的最新成员,也就是第206名成员国。 [17]  2016年6月3日,国际奥委会发表公报宣布组成难民奥林匹克运动队,以迎接即将到来的里约奥运会。这支难民奥林匹克运动队由10名运动员组成,其中包括5名南苏丹难民、2名叙利亚难民、2名刚果(金)难民和1名埃塞俄比亚难民。他们将参加里约奥运会田径、游泳和柔道等项目的比赛。 [18]  全会同时表决通过了空手道、滑板、竞技攀岩、冲浪和棒垒球这5大项运动进入2020年东京奥运会的竞赛项目。 [19]  2017年7月11日,国际奥委会130届全会举行投票,一致决定2024年和2028年夏季奥运会的承办城市将同时产生,唯一的悬念是两个申办城市洛杉矶和巴黎谁先举办。 [20]  2019年6月23日,国际奥委会在瑞士洛桑举行国际奥委会新总部的揭幕。 [21] 
收起全文
精华内容
下载资源
问答
  • IOC的相关理解总结

    万次阅读 多人点赞 2020-04-20 13:54:07
    一、对IOC和DI的基本认识 (一)理解IoC,即“控制反转” (二)IoC具体做什么? (三)理解IoC和DI的关系 二、对IOC容器初始化的理解 四、对DI依赖注入的理解(主要是) 参考书籍、文献和资料 一、对IOC和DI...

    目录

    当前没有去添加对应的源码,只是自己的一些总结,可能理解有错误或不到位,还请指出。

    一、对IOC和DI的基本认识

    (一)理解IoC,即“控制反转”

    (二)IoC具体做什么?

    (三)理解IoC和DI的关系

    二、对IOC容器初始化的理解

    三、对DI依赖注入的理解

    参考书籍、文献和资料


    当前没有去添加对应的源码,只是自己的一些总结,可能理解有错误或不到位,还请指出。

    一、对IOC和DI的基本认识

    (一)理解IoC,即“控制反转”

    在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:

    谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建以及外部资源获取(不只是对象包括比如文件等)

    为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转,依赖对象的获取被反转了

    (二)IoC具体做什么?

    IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。

    • 传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;
    • 有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
    • IoC对编程实现由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找

    (三)理解IoC和DI的关系

    DI—Dependency Injection,即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

    理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:

    谁依赖于谁:当然是应用程序依赖于IoC容器;

    为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;

    谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;

    ●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。

    IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”

    二、对IOC容器初始化的理解

    IOC容器初始化的基本步骤主要是两个方面:

    • 初始化的入口由容器实现中的refresh()方法调用来完成。
    • 对Bean定义载入IOC容器使用的方法是loadBeanDefinition()。

    大致过程如下:

    • 通过ReasourceLoader来完成资源文件的定位,DefaultResourceLoader是默认的实现,同时上下文本身就给出了ResourceLoader的实现,可以通过类路径、文件系统、URL等方式来定位资源
    • 如果XmlBeanFactory作为IOC容器,那么需要为它指定Bean定义的资源,也就是说Bean定义文件是通过抽象成Resource来被IOC容器处理,容器通过BeanDefinitionReader来完成定义信息的解析和Bean信息的注册,往往使用XmlBeanDefinitionReader来解析Bean的XML定义文件---实际的处理过程是委托给BeanDefinitionParserDelegate来完成的,从而得到Bean的定义信息,这些信息在Spring中使用BeanDefinition来表示(这个名字可以让我们想到loadBeanDefinition()、registerBeanDefinition()这些相关的方法,他们都是为处理BeanDefinition服务的)。
    • 解析得到BeanDefinition以后,需要在IOC容器中注册,这由IOC实现BeanDefinitionRegister接口来实现,注册过程就是在IOC容器内容维护一个HashMap来保存得到的BeanDefinition的过程,这个HashMap是IOC容器持有Bean信息的场所,以后Bean的操作都是围绕这个HashMap来实现
    • 之后我们通过BeanFactory和ApplicationContext来享受Spring IOC的服务了,在使用IOC容器的时候我们注意到,除了少量粘合代码,绝大多数以正确IOC风格编写的应用程序代码完全不关心如何到达工厂,因为容器将把这些对象与容器管理的其他对象钩在了一起,基本的策略是把工厂放到已知的地方,最好放在对预期使用的上下文有意义的地方,以及代码要实际访问工厂的地方。
    • Spring本身提供了对声明式载入Web应用程序用法的应用程序上下文,并将其存储在ServletContext的框架实现中

    三、对DI依赖注入的理解

    当Spring IOC容器完成了Bean定义资源的定位、载入和解析注册,IOC容器就可以管理Bean定义的相关数据了,但是此时IOC容器还没有对所管理的Bean进行依赖注入,依赖注入 在以下两种情况下发生:

    • 用户第一次调用getBean()方法时,IOC容器触发依赖注入。
    • 当用户在配置文件中将<bean>元素配置了lazy-init=false属性时,即让容器在解析注册Bean定义时进行预实例化,触发依赖注入。

    Beanfactory接口定义了Spring IOC容器的基本功能规范,是Spring IOC容器所应遵守的最低层和最基本的编程规范。BeanFactory接口中定义了几个getBean()方法,用于用户向IOC容器索取被管理的Bean的方法,通过分析其子类的具体实现来理解Spring IOC容器在用户索取Bean时如何完成依赖注入

    • getBean方法肯定不陌生,必经之路,然后调用doGetBean,进来以后首先会执行transformedBeanName找别名,看你的Bean上面是否起了别名。然后进行很重要的一步,getSingleton,这段代码就是从你的单例缓存池中获取Bean的实例。那么你第一次进来肯定是没有的,缓存里肯定是拿不到的。也就是一级缓存里是没有的。那么它怎么办呢?他会尝试去二级缓存中去拿,但是去二级缓存中拿并不是无条件的,首先要判断isSingletonCurrentlyInCreation(beanName)他要看你这个对象是否正在创建当中,如果不是直接就退出该方法,如果是的话,他就会去二级缓存earlySingletonObjects里面取,如果没拿到,它还接着判断allowEarlyReference这个东西是否为true。它的意思是说,是否允许让你从单例工厂对象缓存中去拿对象。默认为true。好了,此时如果进来那么就会通过singletonFactory.getObject()去单例工厂缓存中去拿。然后将缓存级别提升至二级缓存也就早期暴露的缓存。
    • getSingleton执行完以后会走dependsOn方法,判断是否有dependsOn标记的循环引用,有的话直接卡死,抛出异常。比如说A依赖于B,B依赖于A 通过dependsOn注解去指定。此时执行到这里就会抛出异常。这里所指并非是构造函数的循环依赖。
    • beforeSingletonCreation在这里方法里,就把你的对象标记为了早期暴露的对象,提前暴露对象用于创建Bean的实例
    • 紧接着就走创建Bean的流程开始。在创建Bean之前执行了一下resolveBeforeInstantiation。它的意思是说,代理AOPBean定义注册信息但是这里并不是实际去代理你的对象,因为对象还没有被创建。只是代理了Bean定义信息,还没有被实例化把Bean定义信息放进缓存,以便我想代理真正的目标对象的时候,直接去缓存里去拿。
    • 接下来就真正的走创建Bean流程,首先走进真正做事儿的方法doCreateBean然后找到createBeanInstance这个方法,在这里面它将为你创建你的Bean实例信息(Bean的实例)。如果说创建成功了,那么就把你的对象放入缓存中去(将创建好的提前曝光的对象放入singletonFactories三级缓存中)将对象从二级缓存中移除因为它已经不是提前暴露的对象了。但是。如果说在createBeanInstance这个方法中在创建Bean的时候它会去检测你的依赖关系,会去检测你的构造器。然后,如果说它在创建A对象的时候,发现了构造器里依赖了B,然后它又会重新走getBean的这个流程,当在走到这里的时候,又发现依赖了A此时就会抛出异常。为什么会抛出异常,因为,走getBean的时候他会去从你的单例缓存池中去拿,因为你这里的Bean还没有被创建好。自然不会被放进缓存中,所以它是在缓存中拿不到B对象的。反过来也是拿不到A对象的。造成了死循环故此直接抛异常。这就是为什么Spring IOC不能解决构造器循环依赖的原因因为你还没来的急放入缓存你的对象是不存在的。所以不能创建。同理@Bean标注的循环依赖方法也是不能解决的,跟这个同理。那么多例就更不能解决了。为什么?因为在走createBeanInstance的时候,会判断是否是单例的Bean定义信息mbd.isSingleton();如果是才会进来。所以多例的Bean压根就不会走进来,而是走了另一段逻辑,这里不做介绍。至此,构造器循环依赖和@Bean的循环依赖还有多例Bean的循环依赖为什么不能解决已经解释清楚。然后如果说,Bean创建成功了。那么会走后面的逻辑。
    • 将创建好的Bean放入缓存,addSingletonFactory方法就是将你创建好的Bean放入三级缓存中,并且移除早期暴露的对象。
    • 通过populateBean给属性赋值,我们知道,创建好的对象,并不是一个完整的对象,里面的属性还没有被赋值。所以这个方法就是为创建好的Bean为它的属性赋值。并且调用了我们实现的的XXXAware接口进行回调初始化,然后调用我们实现的Bean的后置处理器,给我们最后一次机会去修改Bean的属性

    参考书籍、文献和资料

    1.https://www.iteye.com/blog/jinnianshilongnian-1413846

    2.《Sring 5 核心原理与30个类手写实战》,谭勇徳,中国公信出版社,2019.

    展开全文
  • IOC

    千次阅读 2018-05-19 11:51:46
    [IOC] 1. ioc 简介 1.1 ioc 定义 ioc (Inversion of Control, 控制反转)把创建对象的操作交给框架,亦被称为 DI(Dependency Injection, 依赖注入)。 为什么叫做 “控制反转” 呢?之前,我们想要一个对象...

    [IOC]

    1. ioc 简介

    1.1 ioc 定义

    ioc (Inversion of Control, 控制反转)把创建对象的操作交给框架,亦被称为 DI(Dependency Injection, 依赖注入)。

    为什么叫做 “控制反转” 呢?之前,我们想要一个对象都是 new 出来的,天天需要 new 对象是不是感觉有点麻烦。有人就想到了,把这些简单重复的工作也交给框架做。本来需要我们向框架 “射入” 对象,现在框架自己能产生对象了,这不正是 控制反转 吗?于是,就有了这个响亮的名字。

    1.2 ioc 目标

    其实定义中已经把 ioc 的目标说清楚了。这里,再强调一下:把创建对象的操作交给框架,“解放程序员的生产力”。

    下面代码是 ioc 的使用用例,它可实现 customerService 变量的自动注入。本文的目标是实现 ioc ,也就是使得下面代码可用。

        // 使用了基于注解实现的 ioc 代码
        @Controller
        public class CustomerController {
    
            // 这里可以自动注入 CustomerService 对象
            @InJect
            private CustomerService customerService;
    
            ...
    
        }
    

    ioc 的实现主要有两种形式:1)声明式;2)注解。其中,声明式是基于 xml 配置文件来做的,这种方式对 jdk 版本无要求,兼容性强,但相注解方式较冗杂;而注解方式,需要 jdk1.5 以上(因为从 jdk1.5 才有了注解),但它更灵活、更简洁。鉴于现在很少有人在使用 jdk1.5 之前的版本,本文将基于注解实现 ioc

    2. ioc 实现

    2.1 实现关键

    1. 如何标识出类中哪些变量需要注入;
    2. 怎样生成可用于注入的对象实例以及如何存储它们;
    3. 何时注入;

    2.2 详细过程

    1) 创建注解 InJect 用它标识类中需要注入的属性;

        // InJect.java
        package top.inotwant.annocation;
    
        import java.lang.annotation.ElementType;
        import java.lang.annotation.Retention;
        import java.lang.annotation.RetentionPolicy;
        import java.lang.annotation.Target;
    
        @Target(ElementType.FIELD)  // 元注解,表示 InJect 作用于属性之上
        @Retention(RetentionPolicy.RUNTIME) // 元注解,用于描述 InJect 生存周期
        public @interface InJect {
        }

    2) 创建 Controller Service 注解,它们都作用于类上(比如,1.2 节中 @Controller 作用于 CustomerController 之上)。被它们修饰的类将要求产生对象实例,这个过程将会用到 反射,下面再详细描述该过程。(使用过 Spring 框架的是不是对这两个注解很熟悉)

        // Controller.java
        package top.inotwant.annocation;
    
        import java.lang.annotation.ElementType;
        import java.lang.annotation.Retention;
        import java.lang.annotation.RetentionPolicy;
        import java.lang.annotation.Target;
    
        @Target(ElementType.TYPE)   // 元注解,表示 Controller 作用于类之上
        @Retention(RetentionPolicy.RUNTIME)
        public @interface Controller {
    
        }
    
        // Service.java
        package top.inotwant.annocation;
    
        import java.lang.annotation.ElementType;
        import java.lang.annotation.Retention;
        import java.lang.annotation.RetentionPolicy;
        import java.lang.annotation.Target;
    
        @Target(ElementType.TYPE)
        @Retention(RetentionPolicy.RUNTIME)
        public @interface Service {
    
        }

    3) 自定义类加载器加载包下的所有 java 文件,并从中获取被上面两个注解之一修饰的类的元类 Class<?> 有了这些元类,我们就可以使用反射产生对应的对象实例了。

    ClassUtil 工具类中的 loadClassSet(String packageName) 静态方法实现了该逻辑。它将返回 packageName 指定的包下所有类的元类。

    ClassHelper 帮助类实现了对上面两个注解之一修饰类的元类的抽取。

        // ClassUtil.java
        package top.inotwant.utils;
    
        import java.io.File;
        import java.io.FileFilter;
        import java.io.IOException;
        import java.net.JarURLConnection;
        import java.net.URL;
        import java.util.Enumeration;
        import java.util.HashSet;
        import java.util.Set;
        import java.util.jar.JarEntry;
        import java.util.jar.JarFile;
    
        public final class ClassUtil {
    
            /**
             * 获取类加载器
             */
            public static ClassLoader getClassLoader() {
                return Thread.currentThread().getContextClassLoader();
            }
    
            /**
             * 加载指定类
             */
            public static Class<?> loadClass(String className) {
                try {
                    // TODO 注意 class.forName 与 ClassLoader.loadClass 的区别(关于 static 是否静态初始化)
                    // 注意第二个参数,一定要设置为 true 。否则,在加载类时不会运行 static 块,这将影响一部分类的初始化。
                    return Class.forName(className, true, getClassLoader());
                } catch (ClassNotFoundException e) {
                    throw new RuntimeException(e);
                }
            }
    
            /**
             * 加载包下所有类
             * @param packageName 为包名,比如 “top.inotwant.sample”
             */
            public static Set<Class<?>> loadClassSet(String packageName) {
                String packagePath = packageName.replace(".", "/");
                try {
                    Set<Class<?>> result = new HashSet<>();
                    // getResources 的使用请看 API
                    Enumeration<URL> resources = getClassLoader().getResources(packagePath);
                    while (resources.hasMoreElements()) {
                        URL currentURL = resources.nextElement();
                        if ("file".equals(currentURL.getProtocol())) {
                            String path = currentURL.getPath().replaceAll("%20", " ");
                            addClass(path, packageName, result);
                        } else if ("jar".equals(currentURL.getProtocol())) {    // 此处为了加载文件夹下 `jar` 中所包含的所有类文件,若不理解可忽略此处,不影响总体
                            JarURLConnection conn = (JarURLConnection) currentURL.openConnection();
                            JarFile jarFile = conn.getJarFile();
                            Enumeration<JarEntry> entries = jarFile.entries();
                            while (entries.hasMoreElements()) {
                                JarEntry jarEntry = entries.nextElement();
                                String jarEntryName = jarEntry.getName();
                                if (jarEntryName.endsWith(".class")) {
                                    String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");
                                    result.add(loadClass(className));
                                }
                            }
                        }
                    }
                    return result;
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
    
            private static void addClass(String path, String packageName, Set<Class<?>> result) {
                File[] files = new File(path).listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File file) {
                        return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();
                    }
                });
                if (files != null) {
                    for (File file : files) {
                        if (file.isFile()) {
                            String subFileName = file.getName();
                            String className = subFileName.substring(0, subFileName.lastIndexOf("."));
                            result.add(loadClass(packageName + "." + className));
                        } else if (file.isDirectory()) {
                            // 递归
                            addClass(file.getAbsolutePath(), packageName + "." + file.getName(), result);
                        }
                    }
                }
            }
        }
    
    
        // ClassHelper.java
        package top.inotwant.helper;
    
        import top.inotwant.annocation.Controller;
        import top.inotwant.annocation.Service;
        import top.inotwant.utils.ClassUtil;
    
        import java.util.HashSet;
        import java.util.Set;
    
        /**
         * Class 帮助类
         */
        public final class ClassHelper {
    
            private static Set<Class<?>> CLASS_SET;
    
            static {
                String basePackage = "指定包";
                CLASS_SET = ClassUtil.loadClassSet(basePackage);
            }
    
            /**
             * 加载 base package 下的所有类
             */
            public static Set<Class<?>> getClassSet() {
                return CLASS_SET;
            }
    
            /**
             * 获取加载的由 service 标注的所有类
             */
            public static Set<Class<?>> getServiceClassSet() {
                Set<Class<?>> result = new HashSet<>();
                for (Class<?> clazz : CLASS_SET) {
                    if (clazz.isAnnotationPresent(Service.class))
                        result.add(clazz);
                }
                return result;
            }
    
            /**
             * 获取加载的由 controller 标注的所有类
             */
            public static Set<Class<?>> getControllerClassSet() {
                Set<Class<?>> result = new HashSet<>();
                for (Class<?> clazz : CLASS_SET) {
                    if (clazz.isAnnotationPresent(Controller.class))
                        result.add(clazz);
                }
                return result;
            }
    
            /**
             * 获取框架管理的 bean (包含, service controller)
             */
            public static Set<Class<?>> getBeanClassSet() {
                Set<Class<?>> result = new HashSet<>();
                result.addAll(getServiceClassSet());
                result.addAll(getControllerClassSet());
                return result;
            }
        }

    4) 利用上面的元类,使用反射生成它们对应的对象实例。

    BeanHelper 中的静态块中实现这个逻辑。这些对象实例中包含了可用于注入的(与 @Service 对应的),它们被存储在 map 中,以 <Class,Object> 键值对的形式,是不是很容易理解。

        // BeanHelper.java
        package top.inotwant.helper;
    
        import java.util.HashMap;
        import java.util.Map;
        import java.util.Set;
    
        /**
         * bean 帮助类
         */
        public final class BeanHelper {
    
            private final static Map<Class<?>, Object> BEAN_MAP = new HashMap<>();
    
            static {
                Set<Class<?>> beanClassSet = ClassHelper.getBeanClassSet();
                for (Class<?> clazz : beanClassSet) {
                    BEAN_MAP.put(clazz, getInstance(clazz));
                }
            }
    
            /**
             * 获取类对应的实例
             */
            @SuppressWarnings("unchecked")
            private static <T> T getInstance(Class<?> clazz) {
                try {
                    return (T) clazz.newInstance();
                } catch (InstantiationException | IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }
    
            /**
             * 获取 bean 映射
             */
            public static Map<Class<?>, Object> getBeanMap() {
                return BEAN_MAP;
            }
    
            /**
             * 获取 bean
             */
            @SuppressWarnings("unchecked")
            public static <T> T getBean(Class<T> clazz) {
                Object obj = BEAN_MAP.get(clazz);
                if (obj != null)
                    return (T) obj;
                else {
                    throw new RuntimeException("can't get bean by class: " + clazz.getSimpleName());
                }
            }
        }
    

    5) 注入

    IocHelper 帮助类的 static 块中完成最后一步 注入。其中的逻辑很简单,我们把所有的 bean 遍历一遍,每一次迭代查看该 bean 的各个属性是否标注 InJect 。如果标注了,就从 beanMap 中获取相应的对象实例进行注入。

        package top.inotwant.helper;
    
        import top.inotwant.annocation.InJect;
        import top.inotwant.utils.ArrayUtil;
        import top.inotwant.utils.CollectionUtil;
        import top.inotwant.utils.ReflectUtil;
    
        import java.lang.reflect.Field;
        import java.util.Map;
    
        /**
         * ioc 实现类
         */
        public final class IocHelper {
    
            static {
                Map<Class<?>, Object> beanMap = BeanHelper.getBeanMap();
                if (CollectionUtil.isNotEmpty(beanMap)) {   // 判断集合是否为空
                    for (Map.Entry<Class<?>, Object> entry : beanMap.entrySet()) {
                        Class<?> clazz = entry.getKey();
                        Object obj = entry.getValue();
                        // TODO 切勿调成 getFields() ,它不能获取私有属性
                        Field[] fields = clazz.getDeclaredFields();
                        if (ArrayUtil.isNotEmpty(fields)) { // 判断数组是否
                            for (Field field : fields) {
                                if (field.isAnnotationPresent(InJect.class)) {
                                    Object newValue = BeanHelper.getBean(field.getType());
                                    ReflectUtil.modifyField(obj, field, newValue);  // 注入
                                }
                            }
                        }
                    }
                }
            }
    
        }

    6) 初始化 ioc

    前面 5 步已经实现了 ioc,并且可通过系统初始化时加载 IocHelper.class 让它起到作用(想一想为什么只需要加载一个类就可以?)。但是,我建议再创建如下一个类,让加载更集中、初始化的逻辑更清晰。

        package top.inotwant;
    
        import top.inotwant.helper.*;
        import top.inotwant.utils.ClassUtil;
    
        /**
         * 加载相关的 helper 类
         */
        public final class HelperLoader {
    
            public static void init() {
                Class<?>[] classes = {
                        ClassHelper.class,
                        BeanHelper.class,
                        IocHelper.class
                };
                for (Class<?> clazz : classes) {
                    ClassUtil.loadClass(clazz.getName());
                }
            }
        }

    至此,1.2 节中的代码已经可以使用。

    3. 参考

    架构探险(张勇)

    展开全文
  • ioc

    2018-09-23 09:29:14
    IOC:比如有一个类,在类中有一个非静态的方法,当我们要在另一个类中去调用这个类的方法,创建这个类的对象,使用对象点的方式去调用方法,创建类对象的过程是new出来的 而ioc不是通过new来创建对象,而是交给...

    IOC:比如有一个类,在类中有一个非静态的方法,当我们要在另一个类中去调用这个类的方法,创建这个类的对象,使用对象点的方式去调用方法,创建类对象的过程是new出来的

    而ioc不是通过new来创建对象,而是交给spring的配置文件去创建对象

    Spring是一站式框架,在其三层结构中,他的每一层都提供了不同的技术

    web层 springmvc

    Service层 spring ioc

    dao层 jdbc模板

     

    Spring 的IOC操作

    1.ioc的配置方式

    2.ioc的注解方式

     

    ioc底层原理用到的技术

    1).xml配置文件

    2).dom4j解析xml

    3).工厂设计模式

    4).反射

     

    注解的写法 @注解名称(属性名=属性值)

    注解可以使用在类上面,可以使用在方法、属性上面

    使用注解可以完成功能

    使用注解必须导入aop包

    展开全文
  • IoC

    2014-03-07 13:20:41
    IoC: Inversion of Control,控制反转, 控制权从应用程序转移到框架(如IoC容器),是框架共有特性   1、为什么需要IoC容器 1.1、应用程序主动控制对象的实例化及依赖装配  Java代码  ...
    IoC: Inversion of Control,控制反转, 控制权从应用程序转移到框架(如IoC容器),是框架共有特性

     

    1、为什么需要IoC容器
    1.1、应用程序主动控制对象的实例化及依赖装配 
    Java代码  收藏代码
    1. A a = new AImpl();  
    2. B b = new BImpl();  
    3. a.setB(b);  
    本质:创建对象,主动实例化,直接获取依赖,主动装配 
    缺点:更换实现需要重新编译源代码
               很难更换实现、难于测试
               耦合实例生产者和实例消费者 

    Java代码  收藏代码
    1. A a = AFactory.createA();  
    2. B b = BFactory.createB();  
    3. a.setB(b);  
     
    本质:创建对象,被动实例化,间接获取依赖,主动装配  (简单工厂) 
    缺点:更换实现需要重新编译源代码
               很难更换实现、难于测试


    Java代码  收藏代码
    1. A a = Factory.create(“a”);  
    2. B b = Factory.create(“b”);  
    3. a.setB(b);   

      <!—配置.properties-->
    Xml代码  收藏代码
    1. a=AImpl  
    2. b=BImpl  
     
    本质:创建对象,被动实例化,间接获取依赖, 主动装配
            (工厂+反射+properties配置文件、
               Service Locator、注册表) 
    缺点:冗余的依赖装配逻辑


    我想直接:
        //返回装配好的a
    Java代码  收藏代码
    1. A a = Factory.create(“a”);   

                  
    1.2、可配置通用工厂:工厂主动控制,应用程序被动接受,控制权从应用程序转移到工厂
    Java代码  收藏代码
    1. //返回装配好的a   
    2. A a = Factory.create(“a”);  
       <!—配置文件-->
    Java代码  收藏代码
    1. <bean id=“a” class=“AImpl”>  
    2.     <property name=“b” ref=“b”/>  
    3. </bean>  
    4. <bean id=“b” class=“BImpl”/>  
     本质:创建对象和装配对象, 
              被动实例化,被动接受依赖,被动装配
            (工厂+反射+xml配置文件)
    缺点:不通用

    步骤:
    1、读取配置文件根据配置文件通过反射
    创建AImpl
    2、发现A需要一个类型为B的属性b
    3、到工厂中找名为b的对象,发现没有,读取
    配置文件通过反射创建BImpl
    4、将b对象装配到a对象的b属性上
    【组件的配置与使用分离开(解耦、更改实现无需修改源代码、易于更好实现) 】

    1.3、 IoC(控制反转)容器:容器主动控制
    Java代码  收藏代码
    1. //返回装配好的a   
    2. A a = ApplicationContext.getBean(“a”);  
     <!—配置文件-->
    Java代码  收藏代码
    1. <bean id=“a” class=“AImpl”>  
    2.     <property name=“b” ref=“b”/>  
    3. </bean>  
    4. <bean id=“b” class=“BImpl”/>  
     
    本质:创建对象和装配对象、管理对象生命周期
              被动实例化,被动接受依赖,被动装配
            (工厂+反射+xml配置文件)
    通用 


     

    IoC容器:实现了IoC思想的容器就是IoC容器

    2、IoC容器特点
    【1】无需主动new对象;而是描述对象应该如何被创建即可
             IoC容器帮你创建,即被动实例化;
    【2】不需要主动装配对象之间的依赖关系,而是描述需要哪个服务(组件),
            IoC容器会帮你装配(即负责将它们关联在一起),被动接受装配;
    【3】主动变被动,好莱坞法则:别打电话给我们,我们会打给你;
    【4】迪米特法则(最少知识原则):不知道依赖的具体实现,只知道需要提供某类服务的对象(面向抽象编程),松散耦合,一个对象应当对其他对象有尽可能少的了解,不和陌生人(实现)说话
    【5】IoC是一种让服务消费者不直接依赖于服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原则。

    3、理解IoC容器问题关键:控制的哪些方面被反转了?
    1、谁控制谁?为什么叫反转? ------ IoC容器控制,而以前是应用程序控制,所以叫反转 
    2、控制什么?               ------ 控制应用程序所需要的资源(对象、文件……
    3、为什么控制?             ------ 解耦组件之间的关系 
    4、控制的哪些方面被反转了? ------ 程序的控制权发生了反转:从应用程序转移到了IoC容器。 

    思考:
        1: IoC/DI等同于工厂吗?
        2: IoC/DI跟以前的方式有什么不一样?
    领会:主从换位的思想

     

    4、实现了IoC思想的容器就是轻量级容器吗?
    如果仅仅因为使用了控制反转就认为这些轻量级容器与众不同,就好象在说我的轿车与众不同因为它有四个轮子? 

    容器:提供组件运行环境,管理组件声明周期(不管组件如何创建的以及组件之间关系如何装配的);

    IoC容器不仅仅具有容器的功能,而且还具有一些其他特性---如依赖装配
                 
    控制反转概念太广泛,让人迷惑,后来Martin Fowler 提出依赖注入概念
    Martin Fowler  Inversion of Control Containers and the Dependency Injection pattern  
    http://martinfowler.com/articles/injection.html


    DI

    2、什么是DI
    DI:依赖注入(Dependency Injection) :用一个单独的对象(装配器)来装配对象之间的依赖关系 。



    2、理解DI问题关键
    谁依赖于谁?           -------   应用程序依赖于IoC容器
    为什么需要依赖?        -------   应用程序依赖于IoC容器装配类之间的关系
    依赖什么东西?          -------   依赖了IoC容器的装配功能
    谁注入于谁?            -------   IoC容器注入应用程序
    注入什么东西?          -------   注入应用程序需要的资源(类之间的关系)
     
    更能描述容器其特点的名字——“依赖注入”(Dependency Injection)
    IoC容器应该具有依赖注入功能,因此也可以叫DI容器 

    3、DI优点
        【1】帮你看清组件之间的依赖关系,只需要观察依赖注入的机制(setter/构造器),就可以掌握整个依赖(类与类之间的关系)。
        【2】组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。
        【3】依赖注入的目标并非为软件系统带来更多的功能,而是为了提升组件重用的概率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不用关心具体的资源来自何处、由谁实现。

    使用DI限制:组件和装配器(IoC容器)之间不会有依赖关系,因此组件无法从装配器那里获得更多服务,只能获得配置信息中所提供的那些。 

    4、实现方式
       1、构造器注入
       2、setter注入
       3、接口注入:在接口中定义需要注入的信息,并通过接口完成注入
           @Autowired
           public void prepare(MovieCatalog movieCatalog,
               CustomerPreferenceDao customerPreferenceDao) {
               this.movieCatalog = movieCatalog;
               this.customerPreferenceDao = customerPreferenceDao;
           }



    使用IoC/DI容器开发需要改变的思路
    1、应用程序不主动创建对象,但要描述创建它们的方式。
    2、在应用程序代码中不直接进行服务的装配,但要配置文件中描述哪一个组件需要哪一项服务。容器负责将这些装配在一起。

    其原理是基于OO设计原则的The Hollywood Principle:Don‘t call us, we’ll call you(别找我,我会来找你的)。也就是说,所有的组件都是被动的(Passive),所有的组件初始化和装配都由容器负责。组件处在一个容器当中,由容器负责管理。

    IoC容器功能:实例化、初始化组件、装配组件依赖关系、负责组件生命周期管理。

    本质:
          IoC:控制权的转移,由应用程序转移到框架;
          IoC/DI容器:应用程序主动实例化对象被动等待对象(被动实例化);
          DI:  由专门的装配器装配组件之间的关系;
          IoC/DI容器:应用程序主动装配对象的依赖应用程序被动接受依赖

    关于IoC/DI与DIP之间的关系 详见 http://www.iteye.com/topic/1122310?page=5#2335746

     

    IoC/DI与迪米特法则 详见http://www.iteye.com/topic/1122310?page=5#2335748

    展开全文
  • SpringIoc 实现原理

    万次阅读 多人点赞 2019-04-20 16:44:33
    什么是SpringIOC spring ioc指的是控制反转,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。交由Spring容器统一进行管理,从而实现松耦合 “控制反转”,不是什么技术,而是一种设计思想...
  • IOC

    2011-05-17 17:06:54
    IOC(控制反转,也叫依赖注入):是一种设计模式而不是编程技术。使用IOC后,我们不需要自己去创建某个类的实例,而由IOC容器去创建,当我们需要使用某个对象时,直接到容器中去获取就可以了。 ...
  • Ioc

    2008-06-11 16:08:00
    控制反转(Ioc)模式(又称DI:Dependency Injection)就是Inversion of Control,控制反转。在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制。这称为控制反转。 IoC(Inversion of ...
  • 浅谈IOC--说清楚IOC是什么

    万次阅读 多人点赞 2018-03-29 16:22:44
    什么是IOC3.IOC也叫依赖注入(DI)4.IOC的优缺点5.IOC容器的技术剖析6.IOC容器的一些产品7.参考博文本文旨在用语言(非代码)说清楚IOC到底是什么,没有什么高深的技术,园中的老牛、大虾们看到这里可以绕行了,以免浪费...
  • 【Spring-IOC基础】深入浅出Spring-IOC

    万次阅读 2020-04-20 16:20:03
    IOC(Inversion Of Control) 1.概念: 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency ...
  • IoCIoC基础

    2019-06-02 19:33:22
    上文提到Spring的核心是IoC和AOP,今天开始学习核心之一的IoC,同样是带着IoC是什么,为什么,怎么用来学习IoC IoC是什么 先看看IoC的全名是什么。IoC——Inversion of Control,即“控制反转”。这个可不是什么技术...
  • 谈谈对Spring IOC的理解

    万次阅读 多人点赞 2016-09-21 13:42:59
    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC 、DI这两个概念是模糊不清的,是很难理解的,今天和大家分享网上的一些技术大牛们对Spring...
  • 浅谈 IOC 什么是 IOC

    万次阅读 多人点赞 2019-05-27 14:19:26
    本文以文字为主题,并没有代码案例,仅限于记录自己对于 IOC 的理解,文中也啥特别高深的东西,大牛和大佬可以忽略本文,以免浪费您宝贵的时间 什么是 IOCIOC (Inversion Of Control,控制倒转),是spring...
  • IoCIoC容器基本原理

    千次阅读 2019-06-02 22:10:51
    上一篇学习了IoC的基础知识,明白了IoC是什么,为什么需要使用IoC以及IoC和DI的区别,接下来让我们继续往下学习IoC容器的基本原理。 IoC容器的概念 IoC容器就是具有依赖注入功能的容器,IoC具有负责实例化,定位,...
  • IOC详解

    2020-09-04 23:51:00
    IOC概念 什么是IOC: 控制反转,把对象创建和对象间的调用过程,交给Spring进行管理。 使用IOC可以降低耦合度。 IOC底层原理:XML解析,工厂模式,反射。 图解IOC底层原理: IOC思想基于IOC容器完成的,IOC容器...
  • SpringIOC

    2020-04-10 13:15:11
    SpringIOC开发第一个Spring程序(IOC)springIOC发展史IOC控制反转/依赖注入图解三种方式的区别 开发第一个Spring程序(IOC) ApplicationContext conext = new ClassPathXmlApplicationContext(...
  • ioc编程

    千次阅读 2020-03-29 12:02:35
    一、什么是ioc? 首先要强调的是ioc是一种编程思想,而不是技术。ioc的全称叫inversion of control,即控制反转的意思。那控制反转又是什么意思呢?通俗点来说就是原来你控制的事情,现在不再由你来控制。在java...
  • ioc本质

    2020-05-08 16:57:18
    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC 、DI这两个概念是模糊不清的,是很难理解的,今天和大家分享网上的一些技术大牛们对Spring...
  • Spring IoC

    2019-10-22 17:35:22
    文章目录控制反转(IoC)依赖倒置原则依赖注入(DI)控制反转、依赖倒置、依赖注入的关系Spring IoC的实现方式XML方式注解方式 控制反转(IoCIoC(Inversion of Control),控制反转,IoC不是一门技术,而是一...
  • spring IOC

    2019-06-04 17:45:06
    Spring IOC的初始化过程: Spring IOC的初始化过程 将原本在程序中手动创建对象的控制权,交由Spring框架来管理。 IoC 在其他语言中也有应用,并非 Spirng 特有。 IoC 容器是 Spring 用来实现 IoC 的载体, ...
  • Spring IOC

    2020-02-23 10:24:44
    Spring IOC IOC容器是一个管理bean的容器,在spring的定义中,他要求所有的ioc容器都需要实现接口BeanFactory,他是一个顶级容器接口。 在IOC容器中,默认情况下,Bean都是以单例形式存在的,也就是说getBean方法...
  • Sping IOC

    2019-03-05 16:45:42
    Sping IOCIoC是什么IoC能做什么IoC和DI IoC是什么 Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 101,121
精华内容 40,448
关键字:

ioc