½Ž€ä»‹ï¼š Spring ä½œäØ“çŽ°åœ¨æœ€ä¼˜ç§€çš„æ¡†æž¶ä¹‹ä¸€åQŒå·²è¢«å¹¿æ³›çš„使用åQŒåƈ且有很多对其分æžçš„æ–‡ç« 。本文将从å¦å¤–一个视角试囑։–æžå‡º Spring 框架的作者设è®?Spring 框架的骨骼架构的设计ç†å¿µåQŒæœ‰é‚£å‡ ä¸ªæ ¸å¿ƒç»„ä»Óž¼Ÿä¸ÞZ»€ä¹ˆéœ€è¦è¿™äº›ç»„ä»Óž¼Ÿå®ƒä»¬åˆæ˜¯å¦‚何¾l“åˆåœ¨ä¸€èµähž„æˆ?Spring 的骨骼架构? Spring çš? AOP ç‰ÒŽ€§åˆæ˜¯å¦‚何利用这些基¼‹€çš„骨骼架构æ¥å·¥ä½œçš„? Spring ä¸åˆä½¿ç”¨äº†é‚£äº›è®¾è®¡æ¨¡å¼æ¥å®Œæˆå®ƒçš„˜q™ç§è®¾è®¡çš„?它的˜q™ç§è®¾è®¡ç†å¿µå¯¹å¯¹æˆ‘们以åŽçš„èÊY件设计有何寽Cºï¼Ÿæœ¬æ–‡ž®†è¯¦¾l†è§£½{”这些问题ã€?/p>
Spring 的骨骼架�/strong>
Spring æ€Õd…±æœ‰åå‡ ä¸ª¾l„äšgåQŒä½†æ˜¯çœŸæ£æ ¸å¿ƒçš„¾l„äšgåªæœ‰å‡ 个åQŒä¸‹é¢æ˜¯ Spring 框架的æ€ÖM½“架构图:
从上图ä¸å¯ä»¥çœ‹å‡º Spring 框架ä¸çš„æ ¸å¿ƒ¾l„äšgåªæœ‰ä¸‰ä¸ªåQšCoreã€Context å’?Beansã€‚å®ƒä»¬æž„å»ø™“v了整ä¸?Spring 的骨骼架构。没有它们就ä¸å¯èƒ½æœ‰ AOPã€Web ½{‰ä¸Šå±‚çš„ç‰ÒŽ€§åŠŸèƒ½ã€‚ä¸‹é¢ä¹Ÿž®†ä¸»è¦ä»Ž˜q™ä¸‰ä¸ªç»„件入手分æž?Springã€?/p>
Spring 的设计ç†å¿?/strong>
å‰é¢ä»‹ç»äº?Spring çš„ä¸‰ä¸ªæ ¸å¿ƒç»„ä»Óž¼Œå¦‚æžœå†åœ¨å®ƒä»¬ä¸‰ä¸ªä¸é€‰å‡ºæ ¸å¿ƒçš„è¯åQŒé‚£ž®±éž Beans ¾l„äšg莫属了,ä¸ÞZ½•˜q™æ ·è¯ß_¼Œå…¶å®ž Spring ž®±æ˜¯é¢å‘ Bean 的编½E‹ï¼ˆBOP,Bean Oriented ProgrammingåQ‰ï¼ŒBean åœ?Spring 䏿‰æ˜¯çœŸæ£çš„主角ã€?/p>
Bean åœ?Spring ä¸ä½œç”¨å°±åƒ?Object å¯?OOP çš„æ„ä¹‰ä¸€æ øP¼Œæ²¡æœ‰å¯¹è±¡çš„æ¦‚å¿µå°±åƒæ²¡æœ‰é¢å‘对象编½E‹ï¼ŒSpring 䏿²¡æœ? Bean 也就没有 Spring å˜åœ¨çš„æ„ä¹‰ã€‚å°±åƒä¸€‹Æ¡æ¼”凸™ˆžå°éƒ½å‡†å¤‡å¥½äº†ä½†æ˜¯å´æ²¡æœ‰æ¼”å‘˜ä¸€æ —÷€‚äØ“ä»€ä¹ˆè¦ Bean ˜q™ç§è§’色 Bean æˆ–è€…äØ“ä½•åœ¨ Spring 如æ¤é‡è¦åQŒè¿™ç”?Spring æ¡†æž¶çš„è®¾è®¡ç›®æ ‡å†³å®šï¼ŒSpring ä¸ÞZ½•如椋¹è¡ŒåQŒæˆ‘们用 Spring çš„åŽŸå› æ˜¯ä»€ä¹ˆï¼ŒæƒÏxƒ³ä½ 会å‘çŽ°åŽŸæ¥ Spring 解决了一个éžå¸¸å…³é”®çš„问题他å¯ä»¥è®©ä½ 把对象之间的ä¾èµ–å…³¾p»è{而用é…置文äšgæ¥ç®¡ç†ï¼Œä¹Ÿå°±æ˜¯ä»–çš„ä¾èµ–注入机制。而这个注入关¾pÕdœ¨ä¸€ä¸ªå« Ioc 容器ä¸ç®¡ç†ï¼Œé‚?Ioc 容噍䏿œ‰åˆæ˜¯ä»€ä¹ˆå°±æ˜¯è¢« Bean 包裹的对象。Spring æ£æ˜¯é€šè¿‡æŠŠå¯¹è±¡åŒ…装在 Bean ä¸è€Œè¾¾åˆ°å¯¹˜q™äº›å¯¹è±¡½Ž¡ç†ä»¥åŠä¸€äº›åˆ—é¢å¤–æ“作的目的ã€?/p>
它这¿U设计ç–略完全类ä¼égºŽ Java 实现 OOP 的设计ç†å¿µï¼Œå½“ç„¶äº?Java 本èínçš„è®¾è®¡è¦æ¯?Spring 夿‚太多太多åQŒä½†æ˜¯éƒ½æ˜¯æž„å»ÞZ¸€ä¸ªæ•°æ®ç»“æž„ï¼Œç„¶åŽæ ÒŽ®˜q™ä¸ªæ•°æ®¾l“构设计他的生å˜çŽ¯å¢ƒåQŒåÆˆè®©å®ƒåœ¨è¿™ä¸ªçŽ¯å¢ƒä¸æŒ‰ç…§ä¸€å®šçš„规律在ä¸åœçš„˜q动åQŒåœ¨å®ƒä»¬çš„ä¸åœè¿åЍä¸è®? 计一¾pÕdˆ—与环境或者与其他个体完æˆä¿¡æ¯äº¤æ¢ã€‚è¿™æ ähƒ³æ¥å›ž˜q‡å¤´æƒÏxƒ³æˆ‘们用到的其他框枉™ƒ½æ˜¯å¤§æ…¨ç±»ä¼¼çš„设计ç†å¿µã€?/p>
æ ¸å¿ƒ¾l„äšg如何ååŒå·¥ä½œ
å‰é¢è¯?Bean æ˜?Spring ä¸å…³é”®å› ç´ ï¼Œé‚?Context å’?Core åˆæœ‰ä½•作用呢åQŸå‰é¢å§ Bean 比作一场演å‡ÞZ¸çš„æ¼”员的è¯ï¼Œé‚?Context ž®±æ˜¯˜q™åœºæ¼”出的舞å°èƒŒæ™¯ï¼Œè€?Core 应该ž®±æ˜¯æ¼”出的é“å…·äº†ã€‚åªæœ‰ä»–们在一èµäh‰èƒ½å…·å¤‡èƒ½æ¼”出一场好æˆçš„æœ€åŸºæœ¬çš„æ¡ä»¶ã€‚å½“ç„¶æœ‰æœ€åŸºæœ¬çš„æ¡ä»¶è¿˜ä¸èƒ½ä½¿è¿™åœºæ¼”凸™„±é¢–而出åQŒè¿˜è¦ä»–表演的节目èƒö够的¾_? 彩,˜q™äº›èŠ‚ç›®ž®±æ˜¯ Spring 能æä¾›çš„特色功能了ã€?/p>
æˆ‘ä»¬çŸ¥é“ Bean 包装的是 ObjectåQŒè€?Object 必然有数æ®ï¼Œå¦‚何¾l™è¿™äº›æ•°æ®æä¾›ç”Ÿå˜çŽ¯å¢ƒå°±æ˜?Context è¦è§£å†³çš„问题åQŒå¯¹ Context æ¥è¯´ä»–就是è¦å‘现æ¯ä¸ª Bean 之间的关¾p»ï¼Œä¸ºå®ƒä»¬å¾ç«‹è¿™¿Uå…³¾pÕdƈ且覾l´æŠ¤å¥½è¿™¿Uå…³¾p…R€‚所ä»?Context ž®±æ˜¯ä¸€ä¸?Bean 关系的集åˆï¼Œ˜q™ä¸ªå…³ç³»é›†åˆåˆå« Ioc 容器åQŒä¸€æ—¦å¾ç«‹è“v˜q™ä¸ª Ioc 容器å?Spring ž®±å¯ä»¥äØ“ä½ å·¥ä½œäº†ã€‚é‚£ Core ¾l„äšgåˆæœ‰ä»€ä¹ˆç”¨æ¦ä¹‹åœ°å‘¢åQŸå…¶å®?Core ž®±æ˜¯å‘现ã€å¾ç«‹å’Œ¾l´æŠ¤æ¯ä¸ª Bean 之间的关¾pÀL‰€éœ€è¦çš„ä¸€äº›åˆ—çš„å·¥å…øP¼Œä»Žè¿™ä¸ªè§’度看æ¥ï¼ŒCore ˜q™ä¸ª¾l„äšgå? Util æ›´èƒ½è®©ä½ ç†è§£ã€?/p>
它们之间å¯ä»¥ç”¨ä¸‹å›¾æ¥è¡¨ç¤ºåQ?/p>
å›?2. 三个¾l„äšg关系
˜q™é‡Œž®†è¯¦¾l†ä»‹¾læ¯ä¸ªç»„件内部类的层‹Æ¡å…³¾p»ï¼Œä»¥åŠå®ƒä»¬åœ¨è¿è¡Œæ—¶çš„æ—¶åºé¡ºåºã€‚我们在使用 Spring 是应该注æ„的地方ã€?/p>
Bean ¾l„äšg
å‰é¢å·²ç»è¯´æ˜Žäº?Bean ¾l„äšgå¯?Spring çš„é‡è¦æ€§ï¼Œä¸‹é¢çœ‹çœ‹ Bean ˜q™ä¸ª¾l„äšg弿€Žä¹ˆè®¾è®¡çš„。Bean ¾l„äšgåœ?Spring çš? org.springframework.beans 包下。这个包下的所有类主è¦è§£å†³äº†ä¸‰ä»¶äº‹åQšBean 的定义ã€Bean 的创å»ÞZ»¥åŠå¯¹ Bean 的解æžã€‚对 Spring çš„ä‹É用者æ¥è¯´å”¯ä¸€éœ€è¦å…³å¿ƒçš„ž®±æ˜¯ Bean 的创建,其他两个ç”?Spring åœ¨å†…éƒ¨å¸®ä½ å®Œæˆäº†åQŒå¯¹ä½ æ¥è¯´æ˜¯é€æ˜Žçš„ã€?/p>
Spring Bean 的创建时典型的工厂模å¼ï¼Œä»–çš„™å¶çñ”æŽ¥å£æ˜?BeanFactoryåQŒä¸‹å›¾æ˜¯˜q™ä¸ªå·¥åŽ‚çš„ç‘ô承层‹Æ¡å…³¾p»ï¼š
BeanFactory 有三个å¾c»ï¼šListableBeanFactoryã€HierarchicalBeanFactory å’? AutowireCapableBeanFactoryã€‚ä½†æ˜¯ä»Žä¸Šå›¾ä¸æˆ‘们å¯ä»¥å‘现最¾lˆçš„默认实现¾cÀL˜¯ DefaultListableBeanFactoryåQŒä»–实现了所有的接å£ã€‚é‚£ä¸ÞZ½•è¦å®šä¹‰è¿™ä¹ˆå¤šå±‚次的接å£å‘¢åQŸæŸ¥é˜…这些接å£çš„æºç 和说明å‘玎ͼŒæ¯ä¸ªæŽ¥å£ 都有他ä‹É用的场åˆåQŒå®ƒä¸»è¦æ˜¯äؓ了区分在 Spring 内部在æ“作过½E‹ä¸å¯¹è±¡çš„ä¼ é€’å’Œè½¬åŒ–˜q‡ç¨‹ä¸ï¼Œå¯¹å¯¹è±¡çš„æ•°æ®è®‰K—®æ‰€åšçš„é™åˆ¶ã€‚例å¦? ListableBeanFactory 接å£è¡¨ç¤º˜q™äº› Bean 是å¯åˆ—表的,è€?HierarchicalBeanFactory 表示的是˜q™äº› Bean 是有¾l§æ‰¿å…³ç³»çš„,也就是æ¯ä¸?Bean 有å¯èƒ½æœ‰çˆ?Bean。AutowireCapableBeanFactory 接å£å®šä¹‰ Bean 的自动装é…规则。这四个接å£å…±åŒå®šä¹‰äº?Bean 的集åˆã€Bean 之间的关¾p…R€ä»¥å?Bean è¡ŒäØ“ã€?/p>
Bean çš„å®šä¹‰ä¸»è¦æœ‰ BeanDefinition æè¿°åQŒå¦‚下图说明了这些类的层‹Æ¡å…³¾p»ï¼š
Bean 的定义就是完整的æè¿°äº†åœ¨ Spring 的酾|®æ–‡ä»¶ä¸ä½ 定义的 <bean/> èŠ‚ç‚¹ä¸æ‰€æœ‰çš„ä¿¡æ¯åQŒåŒ…括儿Uå节点。当 Spring æˆåŠŸè§£æžä½ 定义的一ä¸?<bean/> 节点åŽï¼Œåœ?Spring 的内部他ž®Þp¢«è½¬åŒ–æˆ?BeanDefinition å¯¹è±¡ã€‚ä»¥åŽæ‰€æœ‰çš„æ“ä½œéƒ½æ˜¯å¯¹è¿™ä¸ªå¯¹è±¡å®Œæˆçš„ã€?/p>
Bean 的解æžè¿‡½E‹éžå¸¸å¤æ‚,功能被分的很¾l†ï¼Œå› 䨓˜q™é‡Œéœ€è¦è¢«æ‰©å±•的地方很多,必须ä¿è¯æœ‰èƒö够的ç‰|´»æ€§ï¼Œä»¥åº”对å¯èƒ½çš„å˜åŒ–。Bean 的解æžä¸»è¦å°±æ˜¯å¯¹ Spring é…置文äšg的解æžã€‚这个解æžè¿‡½E‹ä¸»è¦é€šè¿‡ä¸‹å›¾ä¸çš„¾cÕd®Œæˆï¼š
当然˜q˜æœ‰å…·ä½“å¯?tag 的解æžè¿™é‡Œåƈ没有列出ã€?/p>
Context ¾l„äšg
Context åœ?Spring çš?org.springframework.context 包下åQŒå‰é¢å·²¾l讲解了 Context ¾l„äšgåœ? Spring ä¸çš„作用åQŒä»–实际上就是给 Spring æä¾›ä¸€ä¸ªè¿è¡Œæ—¶çš„环境,用以ä¿å˜å„个对象的状æ€ã€‚下é¢çœ‹ä¸€ä¸‹è¿™ä¸ªçŽ¯å¢ƒæ˜¯å¦‚ä½•æž„å¾çš„ã€?/p>
ApplicationContext æ˜?Context 的顶¾U§çˆ¶¾c»ï¼Œä»–é™¤äº†èƒ½æ ‡è¯†ä¸€ä¸ªåº”ç”¨çŽ¯å¢ƒçš„åŸºæœ¬ä¿¡æ¯å¤–,他还¾l§æ‰¿äº†äº”个接å£ï¼Œ˜q™äº”个接å£ä¸»è¦æ˜¯æ‰©å±•äº?Context çš„åŠŸèƒ½ã€‚ä¸‹é¢æ˜¯ Context 的类¾l“构图:
åQˆæŸ¥çœ?å›?7 的清晰版æœ?/font>。)
从上图ä¸å¯ä»¥çœ‹å‡º ApplicationContext ¾l§æ‰¿äº?BeanFactoryåQŒè¿™ä¹Ÿè¯´æ˜Žäº† Spring 容器ä¸è¿è¡Œçš„ä¸ÖM½“对象æ˜? BeanåQŒå¦å¤?ApplicationContext ¾l§æ‰¿äº?ResourceLoader 接å£åQŒä‹Éå¾?ApplicationContext å¯ä»¥è®‰K—®åˆîC“Q何外部资æºï¼Œ˜q™å°†åœ?Core ä¸è¯¦¾l†è¯´æ˜Žã€?/p>
ApplicationContext çš„å¾cÖM¸»è¦åŒ…å«ä¸¤ä¸ªæ–¹é¢ï¼š
å†å¾€ä¸‹åˆ†ž®±æ˜¯æŒ‰ç…§æž„å¾ Context 的文件类型,接瀞®±æ˜¯è®‰K—® Context 的方å¼ã€‚è¿™æ ·ä¸€¾U§ä¸€¾U§æž„æˆäº†å®Œæ•´çš?Context ½{‰çñ”层次ã€?/p>
æ€ÖM½“æ¥è¯´ ApplicationContext å¿…é¡»è¦å®Œæˆä»¥ä¸‹å‡ 件事åQ?/p>
Context ä½œäØ“ Spring çš?Ioc 容器åQŒåŸºæœ¬ä¸Šæ•´åˆäº?Spring 的大部分功能åQŒæˆ–者说是大部分功能的基¼‹€ã€?/p>
Core ¾l„äšg
Core ¾l„äšgä½œäØ“ Spring çš„æ ¸å¿ƒç»„ä»Óž¼Œä»–å…¶ä¸åŒ…å«äº†å¾ˆå¤šçš„关键类åQŒå…¶ä¸ä¸€ä¸ªé‡è¦ç»„æˆéƒ¨åˆ†å°±æ˜¯å®šä¹‰äº†èµ„æºçš„访问方å¼ã€‚è¿™¿U把所有资æºéƒ½æŠ½è±¡æˆä¸€ä¸ªæŽ¥å£çš„æ–¹å¼å¾ˆå€¼å¾—在以åŽçš„è®¾è®¡ä¸æ‹¿æ¥å¦ä¹ 。下é¢å°±é‡è¦çœ‹ä¸€ä¸‹è¿™ä¸ªéƒ¨åˆ†åœ¨ Spring 的作用ã€?/p>
下图æ˜?Resource 相关的类¾l“构图:
åQˆæŸ¥çœ?å›?8 的清晰版æœ?/font>。)
从上囑֯以看å‡?Resource 接壞®è£…了儿Uå¯èƒ½çš„资溾cÕdž‹åQŒä¹Ÿž®±æ˜¯å¯¹ä‹É用者æ¥è¯´å±è”½äº†æ–‡äšg¾cÕdž‹çš„ä¸åŒã€‚对资æºçš„æä¾›è€…æ¥è¯ß_¼Œå¦‚何把资æºåŒ…装è“væ¥äº¤¾l™å…¶ä»–äh用这也是一个问题,我们看到 Resource 接壾l§æ‰¿äº?InputStreamSource 接å£åQŒè¿™ä¸ªæŽ¥å£ä¸æœ‰ä¸ª getInputStream æ–ÒŽ³•åQŒè¿”回的æ˜? InputStream ¾c…R€‚è¿™æ äh‰€æœ‰çš„资æºéƒ½è¢«å¯ä»¥é€šè¿‡ InputStream ˜q™ä¸ª¾cÀL¥èŽ·å–åQŒæ‰€ä»¥ä¹Ÿå±è”½äº†èµ„æºçš„æä¾›è€…。å¦å¤–è¿˜æœ‰ä¸€ä¸ªé—®é¢˜å°±æ˜¯åŠ è½½èµ„æºçš„问题åQŒä¹Ÿž®±æ˜¯èµ„æºçš„åŠ è½½è€…è¦¾lŸä¸€åQŒä»Žä¸Šå›¾ä¸å¯ä»¥çœ‹å‡ø™¿™ä¸ªä“Q务是ç”? ResourceLoader 接å£å®ŒæˆåQŒä»–å±è”½äº†æ‰€æœ‰çš„资æºåŠ è²è€…的差异åQŒåªéœ€è¦å®žçŽ°è¿™ä¸ªæŽ¥å£å°±å¯ä»¥åŠ è²æ‰€æœ‰çš„资æºåQŒä»–的默认实现是 DefaultResourceLoaderã€?/p>
下é¢çœ‹ä¸€ä¸?Context å’?Resource 是如何å¾ç«‹å…³¾pÈš„åQŸé¦–先看一下他们的¾cÕd…³¾pÕd›¾åQ?/p>
�9. Context �Resource 的类关系�/font>
从上囑֯以看出,Context 是把资æºçš„åŠ è½½ã€è§£æžå’Œæè¿°å·¥ä½œå§”托¾l™äº† ResourcePatternResolver ¾cÀL¥å®ŒæˆåQŒä»–相当于一个接头ähåQŒä»–把资æºçš„åŠ è²ã€è§£æžå’Œèµ„æºçš„定义整åˆåœ¨ä¸€èµ·ä¾¿äºŽå…¶ä»–组件ä‹É用。Core ¾l„äšgä¸è¿˜æœ‰å¾ˆå¤šç±»ä¼¼çš„æ–¹å¼ã€?/p>
Ioc 容器如何工作
å‰é¢ä»‹ç»äº?Core ¾l„äšgã€Bean ¾l„äšgå’?Context ¾l„äšgçš„ç»“æž„ä¸Žç›æ€º’关系åQŒä¸‹é¢è¿™é‡Œä»Žä½¿ç”¨è€…角度看一下他们是如何˜qè¡Œçš„ï¼Œä»¥åŠæˆ‘们如何è®?Spring 完æˆå„ç§åŠŸèƒ½åQŒSpring 到底能有那些功能åQŒè¿™äº›åŠŸèƒ½æ˜¯å¦‚ä½•å¾—æ¥çš„,下é¢ä»‹ç»ã€?/p>
å¦‚ä½•åˆ›å¾ BeanFactory 工厂
æ£å¦‚å›?2 æè¿°çš„é‚£æ øP¼ŒIoc 容器实际上就æ˜?Context ¾l„äšg¾l“åˆå…¶ä»–两个¾l„äšgå…±åŒæž„å¾äº†ä¸€ä¸?Bean
关系¾|‘,如何构徘q™ä¸ªå…³ç³»¾|‘?构å¾çš„å…¥å£å°±åœ?AbstractApplicationContext ¾cÈš„ refresh
æ–ÒŽ³•ä¸ã€‚这个方法的代ç 如下åQ?/p>
æ¸…å• 1. AbstractApplicationContext.refresh
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } } } |
˜q™ä¸ªæ–ÒŽ³•ž®±æ˜¯æž„徿•´ä¸ª Ioc 容器˜q‡ç¨‹çš„完整的代ç åQŒäº†è§£äº†é‡Œé¢çš„æ¯ä¸€è¡Œä»£ç 基本上ž®×ƒº†è§£å¤§éƒ¨åˆ† Spring 的原ç†å’ŒåŠŸèƒ½äº†ã€?/p>
˜q™æ®µä»£ç 主è¦åŒ…嫘q™æ ·å‡ 个æ¥éª¤åQ?/p>
下颞®Þq»“åˆä»£ç 分æžè¿™å‡ 个˜q‡ç¨‹ã€?/p>
½W¬äºŒä¸‰å¥ž®±æ˜¯åœ¨åˆ›å»ºå’Œé…ç½® BeanFactory。这里是 refresh 也就是刷新酾|®ï¼Œå‰é¢ä»‹ç»äº?Context æœ‰å¯æ›´æ–°çš„å¾c»ï¼Œ˜q™é‡Œæ£æ˜¯å®žçް˜q™ä¸ªåŠŸèƒ½åQŒå½“ BeanFactory å·²å˜åœ¨æ˜¯ž®±æ›´æ–ŽÍ¼Œå¦‚果没有ž®±æ–°åˆ›å¾ã€‚䏋颿˜¯æ›´æ–° BeanFactory 的方法代ç :
protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException( "I/O error parsing bean definition source for " + getDisplayName(), ex); } } |
˜q™ä¸ªæ–ÒŽ³•实现äº?AbstractApplicationContext 的抽象方æ³? refreshBeanFactoryåQŒè¿™ŒDµä»£ç 清楚的说明äº?BeanFactory çš„åˆ›å»ø™¿‡½E‹ã€‚注æ„?BeanFactory 对象的类型的å˜åŒ–åQŒå‰é¢ä»‹¾l了他有很多åç±»åQŒåœ¨ä»€ä¹ˆæƒ…况下使用ä¸åŒçš„å¾c»è¿™éžå¸¸å…³é”®ã€‚BeanFactory 的原始对象是 DefaultListableBeanFactoryåQŒè¿™ä¸ªéžå¸¸å…³é”®ï¼Œå› äØ“ä»–è®¾è®¡åˆ°åŽé¢å¯¹è¿™ä¸ªå¯¹è±¡çš„å¤šç§æ“作åQŒä¸‹é¢çœ‹ä¸€ä¸‹è¿™ä¸ªç±»çš„ç‘ô承层‹Æ¡ç±»å›¾ï¼š
åQˆæŸ¥çœ?å›?10 的清晰版æœ?/font>。)
从这个图ä¸å‘现除äº?BeanFactory 相关的类外,˜q˜å‘çŽîCº†ä¸?Bean çš?register 相关。这åœ? refreshBeanFactory æ–ÒŽ³•䏿œ‰ä¸€è¡?loadBeanDefinitions(beanFactory) ž®†æ‰¾åˆ°ç”案,˜q™ä¸ªæ–ÒŽ³•ž®†å¼€å§‹åŠ è½½ã€è§£æž?Bean 的定义,也就是把用户定义的数æ®ç»“æž„è{åŒ–äØ“ Ioc 容器ä¸çš„特定数殾l“æž„ã€?/p>
˜q™ä¸ª˜q‡ç¨‹å¯ä»¥ç”¨ä¸‹é¢æ—¶åºå›¾è§£é‡ŠåQ?/p>
å›?11. åˆ›å¾ BeanFactory æ—¶åºå›?/font>
åQˆæŸ¥çœ?å›?11 的清晰版æœ?/font>。)
Bean 的解æžå’Œç™»è®°‹¹ç¨‹æ—¶åºå›‘Ö¦‚下:
åQˆæŸ¥çœ?å›?12 的清晰版æœ?/font>。)
创å¾å¥?BeanFactory åŽï¼ŒæŽ¥ä¸‹åŽÀL·»åР䏀äº?Spring 本èín需è¦çš„一些工å…ïL±»åQŒè¿™ä¸ªæ“作在 AbstractApplicationContext çš?prepareBeanFactory æ–ÒŽ³•完æˆã€?/p>
AbstractApplicationContext 䏿ޥ䏋æ¥çš„三行代ç 对 Spring 的功能扩展性è“v了至关é‡è¦çš„作用。å‰ä¸¤è¡Œä¸»è¦æ˜¯è®©ä½ 现在å¯ä»¥å¯¹å·²ç»æž„å¾çš?BeanFactory 的酾|®åšä¿®æ”¹åQŒåŽé¢ä¸€è¡Œå°±æ˜¯è®©ä½ å¯ä»¥å¯¹ä»¥åŽå†åˆ›å»? Bean 的实例对象时æ·ÕdŠ ä¸€äº›è‡ªå®šä¹‰çš„æ“作。所以他们都是扩展了 Spring 的功能,所以我们è¦å¦ä¹ 使用 Spring å¿…é¡»å¯¹è¿™ä¸€éƒ¨åˆ†æžæ¸…楚ã€?/p>
å…¶ä¸åœ?invokeBeanFactoryPostProcessors æ–ÒŽ³•ä¸ä¸»è¦æ˜¯èŽ·å–实现 BeanFactoryPostProcessor 接å£çš„å¾c…R€‚åÆˆæ‰§è¡Œå®ƒçš„ postProcessBeanFactory æ–ÒŽ³•åQŒè¿™ä¸ªæ–¹æ³•的声明如下åQ?/p>
æ¸…å• 3. BeanFactoryPostProcessor.postProcessBeanFactory
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; |
å®ƒçš„å‚æ•°æ˜?beanFactoryåQŒè¯´æ˜Žå¯ä»¥å¯¹ beanFactory åšä¿®æ”¹ï¼Œ˜q™é‡Œæ³¨æ„˜q™ä¸ª beanFactory æ˜? ConfigurableListableBeanFactory ¾cÕdž‹çš„,˜q™ä¹Ÿå°è¯äº†å‰é¢ä»‹¾lçš„ä¸åŒ BeanFactory 所使用的场åˆä¸åŒï¼Œ˜q™é‡Œåªèƒ½æ˜¯å¯é…ç½®çš?BeanFactoryåQŒé˜²æ¢ä¸€äº›æ•°æ®è¢«ç”¨æˆ·éšæ„修改ã€?/p>
registerBeanPostProcessors æ–ÒŽ³•也是å¯ä»¥èŽ·å–用户定义的实çŽîCº† BeanPostProcessor 接å£çš„å¾c»ï¼Œòq¶æ‰§è¡ŒæŠŠå®ƒä»¬æ³¨å†Œåˆ?BeanFactory 对象ä¸çš„ beanPostProcessors å˜é‡ä¸ã€‚BeanPostProcessor ä¸å£°æ˜Žäº†ä¸¤ä¸ªæ–ÒŽ³•åQšpostProcessBeforeInitializationã€postProcessAfterInitialization 分别用于åœ?Bean 对象åˆå§‹åŒ–时执行。å¯ä»¥æ‰§è¡Œç”¨æˆ¯‚‡ªå®šä¹‰çš„æ“ä½œã€?/p>
åŽé¢çš„å‡ è¡Œä»£ç æ˜¯åˆå§‹åŒ–监å¬äº‹ä»¶å’Œå¯¹ç³»¾lŸçš„其他监å¬è€…的注册åQŒç›‘å¬è€…å¿…™åÀL˜¯ ApplicationListener çš„å¾c…R€?/p>
å¦‚ä½•åˆ›å¾ Bean 实例òq¶æž„å»?Bean 的关¾pȽ‘
下颞®±æ˜¯ Bean 的实例化代ç åQŒæ˜¯ä»?finishBeanFactoryInitialization æ–ÒŽ³•开始的ã€?/p>
æ¸…å• 4. AbstractApplicationContext.finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization( ConfigurableListableBeanFactory beanFactory) { // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); } |
从上é¢ä»£ç ä¸å¯ä»¥å‘现 Bean 的实例化是在 BeanFactory ä¸å‘生的。preInstantiateSingletons æ–ÒŽ³•的代ç 如下:
public void preInstantiateSingletons() throws BeansException { if (this.logger.isInfoEnabled()) { this.logger.info("Pre-instantiating singletons in " + this); } synchronized (this.beanDefinitionMap) { for (String beanName : this.beanDefinitionNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX+ beanName); boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( new PrivilegedAction<Boolean>() { public Boolean run() { return ((SmartFactoryBean) factory).isEagerInit(); } }, getAccessControlContext()); } else { isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit(); } if (isEagerInit) { getBean(beanName); } } else { getBean(beanName); } } } } } |
˜q™é‡Œå‡ºçŽ°äº†ä¸€ä¸ªéžå¸”R‡è¦çš„ Bean —â€?FactoryBeanåQŒå¯ä»¥è¯´ Spring 一大åŠçš„æ‰©å±•的功能都与˜q™ä¸ª Bean 有关åQŒè¿™æ˜¯ä¸ªç‰ÒŽ®Šçš?Bean 他是个工åŽ?BeanåQŒå¯ä»¥äñ”ç”?Bean çš?BeanåQŒè¿™é‡Œçš„产生 Bean 是指 Bean 的实例,如果一个类¾l§æ‰¿ FactoryBean 用户å¯ä»¥è‡ªå·±å®šä¹‰äº§ç”Ÿå®žä¾‹å¯¹è±¡çš„æ–¹æ³•åªè¦å®žçŽîC»–çš?getObject æ–ÒŽ³•。然而在 Spring 内部˜q™ä¸ª Bean 的实例对象是 FactoryBeanåQŒé€šè¿‡è°ƒç”¨˜q™ä¸ªå¯¹è±¡çš?getObject æ–ÒŽ³•ž®Þpƒ½èŽ·å–用户自定义äñ”生的对象åQŒä»Žè€ŒäØ“ Spring æä¾›äº†å¾ˆå¥½çš„æ‰©å±•性。Spring èŽ·å– FactoryBean 本èín的对象是在å‰é¢åŠ ä¸?& æ¥å®Œæˆçš„ã€?/p>
å¦‚ä½•åˆ›å¾ Bean 的实例对象以åŠå¦‚何构å»?Bean 实例对象之间的关è”å…³¾pÕd¼ Spring ä¸çš„ä¸€ä¸ªæ ¸å¿ƒå…³é”®ï¼Œä¸‹é¢æ˜¯è¿™ä¸ªè¿‡½E‹çš„‹¹ç¨‹å›¾ã€?/p>
å›?13.Bean 实例创律¹ç¨‹å›?/font>
åQˆæŸ¥çœ?å›?13 的清晰版æœ?/font>。)
如果是普通的 Bean ž®Þq›´æŽ¥åˆ›å»ÞZ»–的实例,是通过调用 getBean æ–ÒŽ³•ã€‚ä¸‹é¢æ˜¯åˆ›å¾ Bean 实例的时åºå›¾åQ?/p>
å›?14.Bean å®žä¾‹åˆ›å¾æ—¶åºå›?/font>
åQˆæŸ¥çœ?å›?14 的清晰版æœ?/font>。)
˜q˜æœ‰ä¸€ä¸ªéžå¸”R‡è¦çš„部分ž®±æ˜¯å»ºç«‹ Bean 对象实例之间的关¾p»ï¼Œ˜q™ä¹Ÿæ˜?Spring æ¡†æž¶çš„æ ¸å¿ƒç«žäº‰åŠ›åQŒä½•æ—¶ã€å¦‚何å¾ç«‹ä»–们之间的关系è¯ïLœ‹ä¸‹é¢çš„æ—¶åºå›¾åQ?/p>
�15.Bean 对象关系建立
åQˆæŸ¥çœ?å›?15 的清晰版æœ?/font>。)
Ioc 容器的扩展点
现在˜q˜æœ‰ä¸€ä¸ªé—®é¢˜å°±æ˜¯å¦‚何让˜q™äº› Bean 对象有一定的扩展性,ž®±æ˜¯å¯ä»¥åŠ å…¥ç”¨æˆ·çš„ä¸€äº›æ“作。那么有哪些扩展点呢åQ?Spring åˆæ˜¯å¦‚何调用到这些扩展点的?
å¯?Spring çš?Ioc 容器æ¥è¯´åQŒä¸»è¦æœ‰˜q™ä¹ˆå‡ 个。BeanFactoryPostProcessoråQ? BeanPostProcessor。他们分别是在构å»?BeanFactory 和构å»?Bean 对象时调用。还有就æ˜? InitializingBean å’?DisposableBean 他们分别是在 Bean 实例创å¾å’Œé”€æ¯æ—¶è¢«è°ƒç”¨ã€‚用户å¯ä»¥å®žçŽ°è¿™äº›æŽ¥å£ä¸å®šä¹‰çš„æ–¹æ³•,Spring ž®×ƒ¼šåœ¨é€‚当的时候调用他们。还有一个是 FactoryBean 他是个特ŒDŠçš„ BeanåQŒè¿™ä¸?Bean å¯ä»¥è¢«ç”¨æˆäh›´å¤šçš„æŽ§åˆ¶ã€?/p>
˜q™äº›æ‰©å±•炚w€šå¸¸ä¹Ÿæ˜¯æˆ‘们使用 Spring æ¥å®Œæˆæˆ‘们特定ä“Q务的地方åQŒå¦‚何精é€?Spring ž®Þqœ‹ä½ 有没有掌æ¡å¥?Spring 有哪些扩展点åQŒåƈ且如何ä‹É用他们,è¦çŸ¥é“如何ä‹É用他们就必须了解他们内在的机ç†ã€‚å¯ä»¥ç”¨ä¸‹é¢ä¸€ä¸ªæ¯”å–ÀL¥è§£é‡Šã€?/p>
我们æŠ?Ioc 容器比作一个箱å,˜q™ä¸ª½Ž±å里有若干个çƒçš„æ¨¡å,å¯ä»¥ç”¨è¿™äº›æ¨¡åæ¥é€ 很多ç§ä¸åŒçš„çƒåQŒè¿˜æœ‰ä¸€ä¸ªé€ è¿™äº›çƒæ¨¡çš„æœºå™¨åQŒè¿™ä¸ªæœºå™¨å¯ä»¥äñ”ç”Ÿçƒæ¨¡ã€‚那么他们的对应å…? ¾pÕd°±æ˜?BeanFactory ž®±æ˜¯é‚£ä¸ªé€ çƒæ¨¡çš„æœºå™¨åQŒçƒæ¨¡å°±æ˜?BeanåQŒè€Œçƒæ¨¡é€ 出æ¥çš„çƒå°±æ˜?Bean 的实例。那å‰é¢æ‰€è¯´çš„å‡ ä¸ªæ‰©å±•ç‚¹åˆåœ¨ä»€ä¹ˆåœ°æ–¹å‘¢åQ?BeanFactoryPostProcessor å¯¹åº”åˆ°å½“é€ çƒæ¨¡è¢«é€ å‡ºæ¥æ—¶åQŒä½ ž®†æœ‰æœÞZ¼šå¯ä»¥å¯¹å…¶åšå‡ºè®‘Ö½“的修æ£ï¼Œä¹Ÿå°±æ˜¯ä»–å¯ä»¥å¸®ä½ ä¿®æ”¹çƒæ¨¡ã€‚è€?InitializingBean å’? DisposableBean æ˜¯åœ¨çƒæ¨¡é€ çƒçš„开始和¾l“æŸé˜¶æ®µåQŒä½ å¯ä»¥å®Œæˆä¸€äº›é¢„备和扫尾工作。BeanPostProcessor ž®±å¯ä»¥è®©ä½ å¯¹çƒæ¨¡é€ 出æ¥çš„çƒåšå‡ºé€‚当的修æ£ã€‚最åŽè¿˜æœ‰ä¸€ä¸? FactoryBeanåQŒå®ƒå¯æ˜¯ä¸€ä¸ªç¥žå¥‡çš„çƒæ¨¡ã€‚è¿™ä¸ªçƒæ¨¡ä¸æ˜¯é¢„先就定型了,而是ç”׃½ æ¥ç»™ä»–确定它的åÅžçŠÓž¼Œæ—¢ç„¶ä½ å¯ä»¥ç¡®å®šè¿™ä¸ªçƒæ¨¡åž‹çš„åÅžçŠÓž¼Œå½“ç„¶ä»–é€ å‡ºæ? çš„çƒè‚¯å®šž®±æ˜¯ä½ 想è¦çš„çƒäº†åQŒè¿™æ ·åœ¨˜q™ä¸ª½Ž±å里尼å¯ä»¥å‘çŽ°æ‰€æœ‰ä½ æƒŒ™¦çš„çƒ
Ioc 容器如何为我所�/strong>
å‰é¢çš„介¾l了 Spring å®¹å™¨çš„æž„å»ø™¿‡½E‹ï¼Œé‚?Spring èƒ½äØ“æˆ‘ä»¬åšä»€ä¹ˆï¼ŒSpring çš?Ioc 容器åˆèƒ½åšä»€ä¹ˆå‘¢åQŸæˆ‘们ä‹Éç”? Spring å¿…é¡»è¦é¦–先构å»?Ioc 容器åQŒæ²¡æœ‰å®ƒ Spring æ— æ³•å·¥ä½œåQŒApplicatonContext.xml ž®±æ˜¯ Ioc 容器的默认酾|®æ–‡ä»Óž¼ŒSpring 的所有特性功能都是基于这ä¸?Ioc 容器工作的,比如åŽé¢è¦ä»‹¾lçš„ AOPã€?/p>
Ioc 它实际上ž®±æ˜¯ä¸ÞZ½ æž„å¾äº†ä¸€ä¸ªé”方,Spring ä¸ÞZ½ æå¥½äº†éª¨éª¼æž¶æž„,˜q™ä¸ª™ì”方到底能å˜å‡ÞZ»€ä¹ˆå¥½çš„东西出æ¥ï¼Œ˜q™å¿…™å»è¦æœ‰ä½ çš„å‚与。那我们怎么å‚与åQŸè¿™ž®±æ˜¯å‰é¢è¯´çš„è¦äº†è§?Spring ä¸é‚£æœ‰äº›æ‰©å±•点,我们通过实现那些扩展ç‚ÒŽ¥æ”¹å˜ Spring çš„é€šç”¨è¡ŒäØ“ã€‚è‡³äºŽå¦‚ä½•å®žçŽ°æ‰©å±•ç‚¹æ¥å¾—到我们想è¦çš„个性结果,Spring 䏿œ‰å¾ˆå¤šä¾‹ååQŒå…¶ä¸?AOP 的实现就æ˜?Spring 本èín实现了其扩展ç‚ÒŽ¥è¾‘Öˆ°äº†å®ƒæƒŒ™¦çš„特性功能,å¯ä»¥æ‹¿æ¥å‚考ã€?/p>
Spring ä¸?AOP ç‰ÒŽ€§è¯¦è§?/strong>
è¦äº†è§?Spring çš?AOP ž®±å¿…™åÕd…ˆäº†è§£çš„动æ€ä»£ç†çš„原ç†åQŒå› ä¸?AOP ž®±æ˜¯åŸÞZºŽåЍæ€ä»£ç†å®žçŽ°çš„ã€‚åŠ¨æ€ä»£ç†è¿˜è¦ä»Ž JDK 本èín说è“vã€?/p>
åœ?Jdk çš?java.lang.reflect 包下有个 Proxy ¾c»ï¼Œå®ƒæ£æ˜¯æž„é€ ä»£ç†ç±»çš„å…¥å£ã€‚这个类的结构入下:
从上囑֑现最åŽé¢å››ä¸ªæ˜¯å…¬æœ‰æ–¹æ³•。而最åŽä¸€ä¸ªæ–¹æ³?newProxyInstance ž®±æ˜¯åˆ›å¾ä»£ç†å¯¹è±¡çš„æ–¹æ³•。这个方法的æºç 如下åQ?/p>
æ¸…å• 6. Proxy. newProxyInstance
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { if (h == null) { throw new NullPointerException(); } Class cl = getProxyClass(loader, interfaces); try { Constructor cons = cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h }); } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } catch (IllegalAccessException e) { throw new InternalError(e.toString()); } catch (InstantiationException e) { throw new InternalError(e.toString()); } catch (InvocationTargetException e) { throw new InternalError(e.toString()); } } |
˜q™ä¸ªæ–ÒŽ³•需è¦ä¸‰ä¸ªå‚敎ͼšClassLoaderåQŒç”¨äºŽåŠ è½½ä»£ç†ç±»çš?Loader ¾c»ï¼Œé€šå¸¸˜q™ä¸ª Loader 和被代ç†çš„类是åŒä¸€ä¸? Loader ¾c…R€‚InterfacesåQŒæ˜¯è¦è¢«ä»£ç†çš„那些那些接å£ã€‚InvocationHandleråQŒå°±æ˜¯ç”¨äºŽæ‰§è¡Œé™¤äº†è¢«ä»£ç†æŽ¥å£ä¸æ–¹æ³•之外的用户自定义的æ“作åQ? 他也是用户需è¦ä»£ç†çš„æœ€¾lˆç›®çš„。用戯‚°ƒç”¨ç›®æ ‡æ–¹æ³•都被代ç†åˆ° InvocationHandler ¾cÖM¸å®šä¹‰çš„唯一æ–ÒŽ³• invoke ä¸ã€‚这在åŽé¢å†è¯¦è§£ã€?/p>
下题q˜æ˜¯çœ‹çœ‹ Proxy 如何产生代熾cÈš„˜q‡ç¨‹åQŒä»–æž„é€ å‡ºæ¥çš„代熾cÕdˆ°åº•æ˜¯ä»€ä¹ˆæ ·åï¼Ÿä¸‹é¢ææ™“å•¦ã€?/p>
å›?17. 创å¾ä»£ç†å¯¹è±¡æ—¶åºå›?/font>
其实从上图ä¸å¯ä»¥å‘现æ£åœ¨æž„é€ ä»£ç†ç±»çš„æ˜¯åœ?ProxyGenerator çš?generateProxyClass 的方法ä¸ã€‚ProxyGenerator ¾cÕdœ¨ sun.misc 包下åQŒæ„Ÿå…´è¶£çš„è¯å¯ä»¥çœ‹çœ‹ä»–çš„æºç ã€?/p>
å‡å¦‚æœ‰è¿™æ ·ä¸€ä¸ªæŽ¥å£ï¼Œå¦‚下åQ?/p>
æ¸…å• 7. SimpleProxy ¾c?/font>
public interface SimpleProxy {
public void simpleMethod1();
public void simpleMethod2();
}
ä»£ç†æ¥ç”Ÿæˆçš„¾cÈ»“构如下:
public class $Proxy2 extends java.lang.reflect.Proxy implements SimpleProxy{ java.lang.reflect.Method m0; java.lang.reflect.Method m1; java.lang.reflect.Method m2; java.lang.reflect.Method m3; java.lang.reflect.Method m4; int hashCode(); boolean equals(java.lang.Object); java.lang.String toString(); void simpleMethod1(); void simpleMethod2(); } |
˜q™ä¸ª¾cÖM¸çš„æ–¹æ³•里é¢å°†ä¼šæ˜¯è°ƒç”¨ InvocationHandler çš?invoke æ–ÒŽ³•åQŒè€Œæ¯ä¸ªæ–¹æ³•也ž®†å¯¹åº”一个属性å˜é‡ï¼Œ˜q™ä¸ªå±žæ€§å˜é‡?m ä¹Ÿå°†ä¼ ç»™ invoke æ–ÒŽ³•ä¸çš„ Method 傿•°ã€‚整个代ç†å°±æ˜¯è¿™æ ·å®žçŽ°çš„ã€?/p>
从å‰é¢ä»£ç†çš„åŽŸç†æˆ‘们知é“åQŒä»£ç†çš„ç›®çš„æ˜¯è°ƒç”¨ç›®æ ‡æ–¹æ³•æ—¶æˆ‘ä»¬å¯ä»¥è½¬è€Œæ‰§è¡?InvocationHandler ¾cÈš„ invoke æ–ÒŽ³•åQŒæ‰€ä»¥å¦‚何在 InvocationHandler ä¸Šåšæ–‡ç« ž®±æ˜¯ Spring 实现 Aop 的关键所在ã€?/p>
Spring çš?Aop 实现是éµå®?Aop è”ç›Ÿçš„çº¦å®šã€‚åŒæ—?Spring åˆæ‰©å±•äº†å®ƒï¼Œå¢žåŠ äº†å¦‚ Pointcutã€Advisor ½{‰ä¸€äº›æŽ¥å£ä‹Éå¾—æ›´åŠ çµ‹z…R€?/p>
䏋颿˜?Jdk 动æ€ä»£ç†çš„¾cÕd›¾åQ?/p>
å›?18. Jdk 动æ€ä»£ç†çš„¾cÕd›¾
上图清楚的显½CÞZº† Spring 引用äº?Aop Alliance 定义的接å£ã€‚姑且ä¸è®¨è®º Spring 如何扩展 Aop
AllianceåQŒå…ˆçœ‹çœ‹ Spring 如何实现代熾cÈš„åQŒè¦å®žçŽ°ä»£ç†¾cÕdœ¨ Spring 的酾|®æ–‡ä»¶ä¸é€šå¸¸æ˜¯è¿™æ ·å®šä¸€ä¸?Bean 的,如下åQ?/p>
æ¸…å• 9. é…置代熾c?Bean
<bean id="testBeanSingleton" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value> org.springframework.aop.framework.PrototypeTargetTests$TestBean </value> </property> <property name="target"><ref local="testBeanTarget"></ref> </property> <property name="singleton"><value>true</value></property> <property name="interceptorNames"> <list> <value>testInterceptor</value> <value>testInterceptor2</value> </list> </property> </bean> |
é…置上看到è¦è®„¡½®è¢«ä»£ç†çš„æŽ¥å£åQŒå’ŒæŽ¥å£çš„å®žçŽ°ç±»ä¹Ÿå°±æ˜¯ç›®æ ‡ç±»åQŒä»¥åŠæ‹¦æˆªå™¨ä¹Ÿå°±åœ¨æ‰§è¡Œç›®æ ‡æ–¹æ³•之å‰è¢«è°ƒç”¨åQŒè¿™é‡?Spring ä¸å®šä¹‰çš„å„ç§å„æ ·çš„æ‹¦æˆªå™¨åQŒå¯ä»¥é€‰æ‹©ä½¿ç”¨ã€?/p>
下é¢çœ‹çœ‹ Spring 如何完æˆäº†ä»£ç†ä»¥åŠæ˜¯å¦‚何调用拦截器的ã€?/p>
å‰é¢æåˆ° Spring Aop 也是实现其自íw«çš„æ‰©å±•ç‚ÒŽ¥å®Œæˆ˜q™ä¸ªç‰ÒŽ€§çš„åQŒä»Ž˜q™ä¸ªä»£ç†¾cÕd¯ä»¥çœ‹å‡ºå®ƒæ£æ˜¯¾l§æ‰¿äº?FactoryBean çš? ProxyFactoryBeanåQŒFactoryBean 之所以特别就在它å¯ä»¥è®©ä½ è‡ªå®šä¹‰å¯¹è±¡çš„åˆ›å¾æ–ÒŽ³•。当然代ç†å¯¹è±¡è¦é€šè¿‡ Proxy ¾cÀL¥åЍæ€ç”Ÿæˆã€?/p>
䏋颿˜?Spring 创å¾çš„代ç†å¯¹è±¡çš„æ—¶åºå›¾ï¼š
Spring 创å¾äº†ä»£ç†å¯¹è±¡åŽåQŒå½“ä½ è°ƒç”¨ç›®æ ‡å¯¹è±¡ä¸Šçš„æ–¹æ³•æ—¶åQŒå°†éƒ½ä¼šè¢«ä»£ç†åˆ° InvocationHandler ¾cÈš„ invoke æ–ÒŽ³•䏿‰§è¡Œï¼Œ˜q™åœ¨å‰é¢å·²ç»è§£é‡Šã€‚在˜q™é‡Œ JdkDynamicAopProxy ¾cÕd®žçŽîCº† InvocationHandler 接å£ã€?/p>
下é¢å†çœ‹çœ?Spring æ˜¯å¦‚ä½•è°ƒç”¨æ‹¦æˆªå™¨çš„ï¼Œä¸‹é¢æ˜¯è¿™ä¸ªè¿‡½E‹çš„æ—¶åºå›¾ï¼š
以上所说的都是 Jdk 动æ€ä»£ç†ï¼ŒSpring ˜q˜æ”¯æŒä¸€¿U?CGLIB ¾cÖM»£ç†ï¼Œæ„Ÿå…´‘£è‡ªå·Þqœ‹å§ã€?/p>
Spring ä¸è®¾è®¡æ¨¡å¼åˆ†æž?/strong>
Spring ä¸ä‹É用的设计模å¼ä¹Ÿå¾ˆå¤šï¼Œæ¯”如工厂模å¼ã€å•例模å¼ã€æ¨¡ç‰ˆæ¨¡å¼ç‰åQŒåœ¨ã€?Webx 框架的系¾lŸæž¶æž„与设计模å¼ã€‹ã€ã€?Tomcat 的系¾lŸæž¶æž„与模å¼è®¾è®¡åˆ†æžã€‹å·²¾l有介ç»åQŒè¿™é‡Œå°±ä¸èµ˜˜qîCº†ã€‚这里主è¦ä»‹¾lä»£ç†æ¨¡å¼å’Œ½{–略模å¼ã€?/p>
ä»£ç†æ¨¡å¼åŽŸç†
ä»£ç†æ¨¡å¼ž®±æ˜¯¾l™æŸä¸€ä¸ªå¯¹è±¡åˆ›å»ÞZ¸€ä¸ªä»£ç†å¯¹è±¡ï¼Œè€Œç”±˜q™ä¸ªä»£ç†å¯¹è±¡æŽ§åˆ¶å¯¹åŽŸå¯¹è±¡çš„å¼•ç”¨ï¼Œè€Œåˆ›å»ø™¿™ä¸ªä»£ç†å¯¹è±¡å°±æ˜¯å¯ä»¥åœ¨è°ƒç”¨åŽŸå¯¹è±¡æ˜¯å¯ä»¥å¢žåŠ ä¸€äº›é¢å¤–çš„æ“ä½œã€‚ä¸‹é¢æ˜¯ä»£ç†æ¨¡å¼çš„结构:
Spring ä¸å¦‚何实çŽîC»£ç†æ¨¡å¼?/strong>
Spring Aop ä¸?Jdk 动æ€ä»£ç†å°±æ˜¯åˆ©ç”¨ä»£ç†æ¨¡å¼æŠ€æœ¯å®žçŽ°çš„ã€‚åœ¨ Spring ä¸é™¤äº†å®žçŽ°è¢«ä»£ç†å¯¹è±¡çš„æŽ¥å£å¤–åQŒè¿˜ä¼šæœ‰ org.springframework.aop.SpringProxy å’? org.springframework.aop.framework.Advised 两个接å£ã€‚Spring ä¸ä‹Éç”¨ä»£ç†æ¨¡å¼çš„¾l“构囑֦‚下:
$Proxy ž®±æ˜¯åˆ›å¾çš„代ç†å¯¹è±¡ï¼Œè€?Subject 是抽象主题,代ç†å¯¹è±¡æ˜¯é€šè¿‡ InvocationHandler æ¥æŒæœ‰å¯¹ç›®æ ‡å¯¹è±¡çš„引用的ã€?/p>
Spring ä¸ä¸€ä¸ªçœŸå®žçš„代ç†å¯¹è±¡¾l“构如下åQ?/p>
æ¸…å• 10 代ç†å¯¹è±¡ $Proxy4
public class $Proxy4 extends java.lang.reflect.Proxy implements org.springframework.aop.framework.PrototypeTargetTests$TestBean org.springframework.aop.SpringProxy org.springframework.aop.framework.Advised { java.lang.reflect.Method m16; java.lang.reflect.Method m9; java.lang.reflect.Method m25; java.lang.reflect.Method m5; java.lang.reflect.Method m2; java.lang.reflect.Method m23; java.lang.reflect.Method m18; java.lang.reflect.Method m26; java.lang.reflect.Method m6; java.lang.reflect.Method m28; java.lang.reflect.Method m14; java.lang.reflect.Method m12; java.lang.reflect.Method m27; java.lang.reflect.Method m11; java.lang.reflect.Method m22; java.lang.reflect.Method m3; java.lang.reflect.Method m8; java.lang.reflect.Method m4; java.lang.reflect.Method m19; java.lang.reflect.Method m7; java.lang.reflect.Method m15; java.lang.reflect.Method m20; java.lang.reflect.Method m10; java.lang.reflect.Method m1; java.lang.reflect.Method m17; java.lang.reflect.Method m21; java.lang.reflect.Method m0; java.lang.reflect.Method m13; java.lang.reflect.Method m24; int hashCode(); int indexOf(org.springframework.aop.Advisor); int indexOf(org.aopalliance.aop.Advice); boolean equals(java.lang.Object); java.lang.String toString(); void sayhello(); void doSomething(); void doSomething2(); java.lang.Class getProxiedInterfaces(); java.lang.Class getTargetClass(); boolean isProxyTargetClass(); org.springframework.aop.Advisor; getAdvisors(); void addAdvisor(int, org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException; void addAdvisor(org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException; void setTargetSource(org.springframework.aop.TargetSource); org.springframework.aop.TargetSource getTargetSource(); void setPreFiltered(boolean); boolean isPreFiltered(); boolean isInterfaceProxied(java.lang.Class); boolean removeAdvisor(org.springframework.aop.Advisor); void removeAdvisor(int)throws org.springframework.aop.framework.AopConfigException; boolean replaceAdvisor(org.springframework.aop.Advisor, org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException; void addAdvice(org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException; void addAdvice(int, org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException; boolean removeAdvice(org.aopalliance.aop.Advice); java.lang.String toProxyConfigString(); boolean isFrozen(); void setExposeProxy(boolean); boolean isExposeProxy(); } |
½{–略模å¼åŽŸç†
½{–略模弙å‘Öæ€ä¹‰ž®±æ˜¯åšæŸäº‹çš„½{–ç•¥åQŒè¿™åœ¨ç¼–½E‹ä¸Šé€šå¸¸æ˜¯æŒ‡å®ŒæˆæŸä¸ªæ“作å¯èƒ½æœ‰å¤š¿U方法,˜q™äº›æ–ÒŽ³•儿œ‰åƒç§‹åQŒå¯èƒ½æœ‰ä¸åŒçš„适应的场åˆï¼Œç„¶è€Œè¿™äº›æ“作方法都有å¯èƒ½ç”¨åˆ°ã€‚å„一个æ“作方法都当作一个实现ç–略,使用者å¯èƒ½æ ¹æ®éœ€è¦é€‰æ‹©åˆé€‚çš„½{–ç•¥ã€?/p>
䏋颿˜¯ç–略模å¼çš„¾l“æž„åQ?/p>
å›?23. ½{–略模å¼çš„结æž?/font>
Spring ä¸ç–略模å¼çš„实现
Spring ä¸ç–略模å¼ä‹É用有多个地方åQŒå¦‚ Bean 定义对象的创å»ÞZ»¥åŠä»£ç†å¯¹è±¡çš„创徽{‰ã€‚这里主è¦çœ‹ä¸€ä¸‹ä»£ç†å¯¹è±¡åˆ›å»ºçš„½{–略模å¼çš„实现ã€?/p>
å‰é¢å·²ç»äº†è§£ Spring çš„ä»£ç†æ–¹å¼æœ‰ä¸¤ä¸ª Jdk 动æ€ä»£ç†å’Œ CGLIB 代ç†ã€‚è¿™ä¸¤ä¸ªä»£ç†æ–¹å¼çš„ä‹Éç”¨æ£æ˜¯ä‹É用了½{–略模å¼ã€‚它的结构图如下所½Cºï¼š
在上é¢ç»“构图ä¸ä¸Žæ ‡å‡†çš„ç–略模å¼ç»“æž„ç¨å¾®æœ‰ç‚¹ä¸åŒï¼Œ˜q™é‡ŒæŠ½è±¡½{–ç•¥æ˜?AopProxy 接å£åQŒCglib2AopProxy å’? JdkDynamicAopProxy 分别代表两秽{–略的实现方å¼ï¼ŒProxyFactoryBean ž®±æ˜¯ä»£è¡¨ Context 角色åQŒå®ƒæ ÒŽ®æ¡äšg选择使用 Jdk ä»£ç†æ–¹å¼˜q˜æ˜¯ CGLIB æ–¹å¼åQŒè€Œå¦å¤–ä¸‰ä¸ªç±»ä¸»è¦æ˜¯æ¥è´Ÿè´£åˆ›å¾å…·ä½“½{–略对象åQŒProxyFactoryBean 是通过ä¾èµ–的方法æ¥å…Œ™”具体½{–略对象的,它是通过调用½{–略对象çš?getProxy(ClassLoader classLoader) æ–ÒŽ³•æ¥å®Œæˆæ“作ã€?/p>
本文通过ä»?Spring çš„å‡ ä¸ªæ ¸å¿ƒç»„ä»¶å…¥æ‰‹ï¼Œè¯•å›¾æ‰‘Ö‡ºæž„å¾ Spring 框架的骨骼架构,˜q›è€Œåˆ†æž?Spring 在设计的一些设计ç†å¿µï¼Œæ˜¯å¦ä»Žä¸æ‰‘Ö‡ºä¸€äº›å¥½çš„è®¾è®¡æ€æƒ³åQŒå¯¹æˆ‘们以厽E‹åºè®¾è®¡èƒ½æä¾›ä¸€äº›æ€èµ\。接ç€å†è¯¦¾l†åˆ†æžäº† Spring 䏿˜¯å¦‚何实现˜q™äº›ç†å¿µçš„,以åŠåœ¨è®¾è®¡æ¨¡å¼ä¸Šæ˜¯å¦‚何ä‹É用的ã€?/p>
é€šè¿‡åˆ†æž Spring ¾l™æˆ‘一个很大的å¯ç¤ºž®±æ˜¯å…¶è¿™å¥—设计ç†å¿µå…¶å®žå¯¹æˆ‘们有很强的借鉴æ„义åQŒå®ƒé€šè¿‡æŠ½è±¡å¤æ‚多å˜çš„对象,˜q›ä¸€æ¥åšè§„范åQŒç„¶åŽæ ¹æ®å®ƒå®šä¹‰çš„è¿™å¥—è§„èŒƒè®¾è®¡å‡ºä¸€ä¸ªå®¹å™¨ï¼Œå®¹å™¨ä¸æž„å»ºå®ƒä»¬çš„å¤æ‚关系åQŒå…¶å®žçŽ°åœ¨æœ‰å¾ˆå¤šæƒ…å†µéƒ½å¯ä»¥ç”¨˜q™ç§¾cÖM¼¼çš„å¤„ç†æ–¹æ³•ã€?/p>
虽然我很æƒÏxŠŠæˆ‘å¯¹ Spring 的想法完全阘q°æ¸…楚,但是所è°?#8220;书丞®½è¨€åQŒè¨€ä¸å°½æ„ã€?#8221;åQŒæœ‰ä»€ä¹ˆä¸å¯ÒŽˆ–è€…ä¸æ¸…楚的地方大家还是看看其æºç å§ã€?/p>
åŽŸæ–‡åœ°å€ http://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/index.html