1.「译」Spring 事务管理:@Transactional 深度解析|by MarcoBehler.md
2.Springä¸BeanFactoryä¸FactoryBeançä½ç¨ä¸åºå«
3.springçç»ä»¶åä½ç¨(springclouç»ä»¶)
「译」Spring 事务管理:@Transactional 深度解析|by MarcoBehler.md
原文链接为: Spring Transaction Management: @Transactional In-Depth | MarcoBehler
你可以通过本文,源码对@Transactional 注解在 Spring 事务管理中的源码运行机制,形成一个简明实用的源码理解。
唯一的源码阅读前提?你需要对数据库 ACID 原则有个大致了解,即数据库事务是源码什么,我们为什么需要它。源码windows xp 源码 下载此外,源码本文没有覆盖分布式事务和反应式事务(reactive transactions),源码尽管在 Spring 中下文提到的源码一些通用原则也是适用的。
在本文中,源码你将学到 Spring 事务抽象框架的源码核心概念,同时会有很多示例代码帮助你理解。源码
相对于 Spring 官方文档,源码本文不会让你迷失在 Spring 的源码上层概念里。 相反你会以不同寻常的源码路径来学习 Spring 事务管理。从底层开始,一层层向上。也就是说,你将从普通原始的2017 直播系统源码 JDBC 事务学起。
普通的 JDBC 事务是如何工作的?如何 start, commit 或 rollback JDBC 事务?最终,他们都做了同样的事来开启和关闭(或称为“管理”)数据库事务。纯 JDBC 事务管理代码如下:这 4 行高度简化的代码,就是 Spring@Transactional 为你在背后做的所有事情。在下一章节中,你将会学到他们是如何工作的。在此之前,我们还有一丁点知识点要补充。
如何使用 JDBC 隔离级别和保存点(savepoints)?如果你已经使用过 Spring@Transactional 注解,你可能碰到过类似用法:我们会在后文更加详细的介绍 Spring 嵌套事务和隔离级别,在这重复提及,是因为这些参数最终可提炼成如下 JDBC 代码:
Spring 或 Spring Boot 的事务是如何工作的?既然现在你对 JDBC 事务有了基础的理解,让我们再去探究下纯粹的 Spring 核心事务。这里所讲都可 1:1 适用于 Spring Boot 和 Sring MVC,但又做了一些补充。到底什么是 Spring 事务管理或事务抽象框架?记住,事务管理可简单理解为:Spring 如何 start, commit 或 rollback JDBC 事务?是不是听着和前文讲得很相似?抓住重点:基于 JDBC 你只有一个方法(setAutocommit(false))来开启事务管理,Spring 提供了许多不同,大盘买卖的源码但更方便的封装来做相同的事情。
如何使用 Spring 编程式事务管理?最初,但现在很少使用方式,是在 Spring 通过编程定义事务:通过TransactionTemplate 或者直接使用 PlatformTransactionManager。代码示例如下「译者注:参见配套项目 BookingServcie 实现」:与 JDBC 示例 比较:尽管这是一个不小的改进,但编程式事务管理并不是 Spring 事务框架主要关注的。相反,声明式事务管理才是重头戏。让我们一探究竟
如何使用 Spring 的@Transactional 注解(声明式事务管理)?让我们看下时下的 Spring 事务管理通常怎么用:这是怎么做到的?没有了冗余的 XML 配置和额外的编码。相反,你只需要做两件事:所以,为了让@Transactional 工作,你需要:现在,我说 Spring 透明的为你处理事务,到底在指什么? 在有了 JDBC 事务示例 的知识储备后,@Transactional 标注的 UserService 可以翻译简化成:这个示例看起来像魔术,让我们继续探究下 Spring 是如何为你自动插入这些连接代码的。
CGLIB & JDK 代理 - 在@Transactional 之下?Spring 不能真的合肥单词优化源码像我上面做的那样,去重写你的 Java 类来插入连接代码(除非你使用字节码增强等高级技术,在这我们暂时忽略它)
你的registerUser() 方法还是只是调用了 userDao.save(user),这是无法实时改变的。但是 Spring 有它的优势。在核心层,它有一个 IoC 容器。它实例化一个UserService 单例并可自动注入到任何需要 UserService 的 Bean 中。不管何时你在一个 Bean 上使用@Transactional,Spring 使用了个小伎俩。它不是直接实例化一个 UserService 原始对象,而是一个 UserService 的事务代理对象。借助 Cglib library 的能力,它可以使用子类继承代理(proxy-through-subclassing)的方式来实现。当然还有其他方式可以构造代理对象(例如 Dynamic JDK proxies 「译者注:这要求代理对象有相应接口类」),这里暂不做展开。
你的UserService 可以动态生成代理类,并且代理可以帮你管理事务。但是怎么修改ui源码并不是代理类本身去处理事务状态(open,commit,close),而是委托给了事务管理器(transaction manager)。
你的UserService 有一个 invoice() 事务方法。它调用了另外一个 InvoiceService 类上的 createPdf() 事务方法。然而从 Spring 看来,这里有 2 个逻辑事务存在:第一个在UserService,另外一个在 InvoiceService。Spring 足够智能知道让两个 @Transactional 标记的方法,在底层使用同一个物理数据库事务。
更改事务传播模式为requires_new 告诉 Spring:createPDF() 需要在它自己的、独立于其他任何已经在的事务里执行。这意味着你的底层代码会打开 2(物理)连接/事务 到数据库。Spring 依旧能够机智的把 2 个 逻辑事务( invoice()/createPdf() )映射到两个不同的物理数据库事务上。
每个 Spring 传播模式在 数据库或 JDBC 连接层面到底做了什么?练习: 在原始 Java 实现那节,我展示了 JDBC 能够对事务进行的所有操作。花几分钟思考下,每个 Spring 传播模式在数据库或 JDBC 连接层面到底做了什么。然后再看下下面的解答。
答案:如你所见,大多数传播模式并没有在数据库或 JDBC 层面做什么事情。更多的是通过 Spring 来组织你的代码,告诉 Spring 如何/什么时候/哪里需要事务处理。
在示例中,任何时候你调用UserService 的 myMethod() 方法,Spring 期望这里有一个打开的事务。它不会为自己开启,相反,在没有已开启事务的情况下调用方法,Spring 会抛出异常。请记住这 “逻辑事务处理”的补充知识点。
@Transactional 上隔离级别(Isolation Levels)代表什么?这是个抖机灵的问题,但当你如下配置的时候,到底发生了什么?哈,这可以简单地等价于:然而数据库事务隔离级别,是一个复杂的主题,你需要自己花些时间去掌握。Pstgres 的官方文档中的 isolation levels 章节,是个不错的入门文档。
最容易踩的@Transactional 的坑?这里有一个 Spring 新手经常踩的坑,看下如下代码:你有一个UserService 类,事务方法 invoice 内部调用了事务方法 createPdf()。所以,当有人调用invoice() 的时候,最终有个多少个物理事务被打开?答案不是 2 个,而是 1 个,为什么呢?让我们回到本文中代理那章节。Spring 为你创建了UserService 代理类,但代理类内部的方法调用,是无法被代理的。也就是说,没有新的事务为你生成。这里有技巧(例如: self-injection 「译者注:参见示例项目 InnerCallSercie」),可以帮助你绕过该限制。但主要收获是:始终牢记代理事务的边界。
在 Spring Boot 或 Spring MVC 中使用@Transactional?我们目前只是讨论了纯粹的核心 Spring 上的用法。那在 Spring Boot 或 Spring MVC 中会有什么使用差异吗?答案是:没有。无论使用何种框架(或更确切地说:Spring 生态系统中的所有框架),您都将始终使用 @Transactional 注解,配合事务管理器,以及@EnableTransactionManagement 注解。没有其他用法了。但是,与 Spring Boot 的唯一区别是,通过 JDBC 自动配置,它会自动设置@EnableTransactionManagement 注解,并为你创建 PlatformTransactionManager。
关于 Spring 回滚的部分,将会在下一次文章修订中补充。Spring Boot 内回滚是通过@Transactional 注解上 rollback 系列配置实现的,读者可查阅源码注释了解使用方式,注释还是写得很完备的,本质上也是根据配置条件,确定何时调用 commit,何时调用 rollback。
Spring 和 JPA / Hibernate 事务管理是如何一起工作的?目标:同步 Spring@Transactional 和 Hibernate / JPA。在这个节点上,你期望 Spring 可以和其他数据库框架,类似 Hibernate(一个流行的 JPA 实现)或 Jooq 等整合。让我来看一个纯粹的 Hibernate 示例(注意:直接使用 Hibernate 还是通过 JPA 使用 Hibernate 都没关系)。用 Hibernate 将UserService 重写如下:然而上述代码有一个大问题:但最终我们还是可以将 Spring 和 Hibernate 无缝整合,也就是说他们其实可以理解对象的事务概念。代码如下:这是怎么做到的?使用 HibernateTransactionManager 有一个非常简单的解决此集成问题的方法:相比在 Spring 配置里使用 DataSourcePlatformTransactionManager,你可以替换成 HibernateTransactionManager(如果使用了原生 Hibernate)或 JpaTransactionManager(如果通过 JPA 使用了 Hibernate)。这个定制化的 HibernateTransactionManager 会确保:与往常一样,一图胜千言(不过请注意,代理和真实服务之间的流程在这被高度抽象和简化了)。
理解 Spring 事务管理后,你应该对 Spring 框架是如何处理事务,以及如何应用于其他 Spring 类库(例如 Spring Boot 或 Spring WebMVC)有了一个很好的了解。最大的收获应是:最终使用哪种框架都无关紧要,这一切可以映射到 JDBC 的基础概念上。正确理解它们(记住:getConnection(),setAutocommit(false),commit()),在以后碰到复杂的企业级项目的使用,你能更容易抓住本质。
到目前为止,你已经对 Spring 事务管理有了全面的了解,希望你在实践中能够灵活运用这些知识,解决实际项目中的事务问题。感谢阅读。
Springä¸BeanFactoryä¸FactoryBeançä½ç¨ä¸åºå«
Spring Frameworkï¼ä»å¹´å¤å¤©ä½ å¯è½å·²ç»å¬è§å¾å¤ç议论ãå¨æ¬æä¸,æå°è¯å¾è§£éSpringè½å®æä»ä¹ï¼åææä¹ä¼è®¤ä¸ºå®è½å¸®å©ä½ å¼åJ2EEåºç¨ç¨åºã å¦ä¸frameworkï¼ ä½ å¯è½æ£å¨æ³âä¸è¿æ¯å¦å¤ä¸ä¸ªçframeworkâãå½å·²ç»æ许å¤å¼æ¾æºä»£ç (åä¸æ) J2EE frameworkæ¶ï¼ä¸ºä»ä¹ä½ åºè¯¥è´¹å¿è¯»è¿ç¯æç« ,æä¸è½½Spring Frameworkï¼ æç¸ä¿¡Springæ¯ç¬ç¹ç,å 为è¥å¹²ä¸ªåå : . å®å®ä½çé¢åæ¯è®¸å¤å ¶ä»æµè¡çframework没æçãSpringå ³æ³¨æä¾ä¸ç§æ¹æ³ç®¡çä½ çä¸å¡å¯¹è±¡ã . Springæ¯å ¨é¢çå模ååçãSpringæåå±çä½ç³»ç»æ,è¿æå³çä½ è½éæ©ä½¿ç¨å®å¤ç«çä»»ä½é¨å,å®çæ¶æä»ç¶æ¯å å¨ç¨³å®çãå æ¤ä»ä½ çå¦ä¹ ä¸ï¼ä½ å¯å¾å°æ大çä»·å¼ãä¾å¦,ä½ å¯è½éæ©ä» ä» ä½¿ç¨Springæ¥ç®ååJDBCç使ç¨,æç¨æ¥ç®¡çææçä¸å¡å¯¹è±¡ã . å®ç设计ä»åºé¨å¸®å©ä½ ç¼åæäºæµè¯ç代ç ãSpringæ¯ç¨äºæµè¯é©±å¨å·¥ç¨ççæ³çframeworkã Springå¯¹ä½ çå·¥ç¨æ¥è¯´ï¼å®ä¸éè¦ä¸ä¸ªä»¥ä¸çframeworkãSpringæ¯æ½å¨å°ä¸ç«å¼è§£å³æ¹æ¡,å®ä½äºä¸å ¸ååºç¨ç¸å ³ç大é¨ååºç¡ç»æãå®ä¹æ¶åå°å ¶ä»framework没æèèå°çå 容ã 尽管å®ä» ä» æ¯ä¸ä¸ªä»å¹´2ææå¼å§çå¼æºå·¥ç¨ï¼ä½Springæè¾é¿çåå²æ ¹åºãè¿ä¸ªå¼æºå·¥ç¨æ¯èµ·æºèªæå¨å¹´åæåºççãExpert One-on-One J2EE设计ä¸å¼åã书ä¸çåºç¡ä»£ç ãè¿æ¬ä¹¦å±ç¤ºäºSpringèåçåºç¡æ¶æãç¶è,è¿ä¸ªåºç¡æ¶æçæ¦å¿µè¦è¿½æº¯å°å¹´çæ©äºæ¶å,并ä¸åæ äºæ为ä¸ç³»åæåçåä¸å·¥ç¨å¼ååºç¡ç»æçç»éªã ä»å¹´1æï¼Springå·²ç»è½æ·äºSourceForgeä¸ãç°å¨æ个å¼å人å,å ¶ä¸6æ¯é«åº¦æå ¥ç积æååã Springçæ¶ææ§çå¥½å¤ å¨æ们è¿å ¥ç»è以åï¼è®©æ们çä¸ä¸Springå¯ä»¥ç»ä¸ä¸ªå·¥ç¨å¸¦æ¥çä¸äºå¥½å¤: . Springè½ææå°ç»ç»ä½ çä¸é´å±å¯¹è±¡,æ è®ºä½ æ¯å¦éæ©ä½¿ç¨äºEJBãå¦æä½ ä» ä» ä½¿ç¨äºStrutsæå ¶ä»çå å«äºJ2EEç¹æAPIsçframeworkï¼ä½ ä¼åç°Springå ³æ³¨äºéçä¸çé®é¢ï¼ã . Springè½æ¶é¤å¨è®¸å¤å·¥ç¨ä¸å¯¹Singletonçè¿å¤ä½¿ç¨ãæ ¹æ®æçç»éªï¼è¿æ¯ä¸ä¸ªä¸»è¦çé®é¢ï¼å®åå°äºç³»ç»çå¯æµè¯æ§åé¢å对象ç¹æ§ã . Springè½æ¶é¤ä½¿ç¨åç§åæ ·æ ¼å¼çå±æ§å®å¶æ件çéè¦,å¨æ´ä¸ªåºç¨åå·¥ç¨ä¸ï¼å¯éè¿ä¸ç§ä¸è´çæ¹æ³æ¥è¿è¡é ç½®ãæ¾ç»æå°è¿·æï¼ä¸ä¸ªç¹å®ç±»è¦æ¥æ¾è¿·å¹»è¬çå±æ§å ³é®åæç³»ç»å±æ§,为æ¤ä¸å¾ä¸è¯»Javadocä¹è³æºç¼ç åï¼æäºSpringï¼ä½ å¯å¾ç®åå°çå°ç±»çJavaBeanå±æ§ãåç½®æ§å¶ç使ç¨(å¨ä¸é¢è®¨è®º)帮å©å®æè¿ç§ç®åã . Springè½éè¿æ¥å£èä¸æ¯ç±»ä¿è¿å¥½çç¼ç¨ä¹ æ¯ï¼åå°ç¼ç¨ä»£ä»·å°å ä¹ä¸ºé¶ã . Spring被设计为让使ç¨å®å建çåºç¨å°½å¯è½å°çä¾èµäºä»çAPIsãå¨Springåºç¨ä¸ç大å¤æ°ä¸å¡å¯¹è±¡æ²¡æä¾èµäºSpringã . 使ç¨Springæ建çåºç¨ç¨åºæäºåå æµè¯ã . Springè½ä½¿EJBç使ç¨æ为ä¸ä¸ªå®ç°éæ©,èä¸æ¯åºç¨æ¶æçå¿ ç¶éæ©ãä½ è½éæ©ç¨POJOsælocal EJBsæ¥å®ç°ä¸å¡æ¥å£ï¼å´ä¸ä¼å½±åè°ç¨ä»£ç ã . Spring帮å©ä½ 解å³è®¸å¤é®é¢èæ é使ç¨EJBãSpringè½æä¾ä¸ç§EJBçæ¿æ¢ç©ï¼å®ä»¬éäºè®¸å¤webåºç¨ãä¾å¦,Springè½ä½¿ç¨AOPæä¾å£°ææ§äºå¡èä¸éè¿ä½¿ç¨EJB容å¨ï¼å¦æä½ ä» ä» éè¦ä¸å个çæ°æ®åºæ交éï¼çè³ä¸éè¦JTAå®ç°ã . Spring为æ°æ®ååæä¾äºä¸è´çæ¡æ¶,ä¸è®ºæ¯ä½¿ç¨JDBCæO/R mapping产åï¼å¦Hibernateï¼ã Springç¡®å®ä½¿ä½ è½éè¿æç®åå¯è¡ç解å³åæ³è§£å³ä½ çé®é¢ãè¿äºç¹æ§æ¯æå¾å¤§ä»·å¼çã Springè½åä»ä¹ï¼ Springæä¾è®¸å¤åè½,å¨æ¤æå°å¿«éå°ä¾æ¬¡å±ç¤ºå ¶å个主è¦æ¹é¢ã ä»»å¡æè¿°ï¼ é¦å ,让æ们æç¡®Springèå´ã尽管Springè¦çäºè®¸å¤æ¹é¢ï¼ä½æ们已ç»ææ¸ æ¥çæ¦å¿µï¼å®ä»ä¹åºè¯¥æ¶ååä»ä¹ä¸åºè¯¥æ¶åã Springç主è¦ç®çæ¯ä½¿J2EEæç¨åä¿è¿å¥½ç¼ç¨ä¹ æ¯ã Springä¸éæ°å¼åå·²æçä¸è¥¿ãå æ¤ï¼å¨Springä¸ä½ å°åç°æ²¡ææ¥å¿è®°å½çå ,没æè¿æ¥æ± ,没æåå¸äºå¡è°åº¦ãè¿äºåæå¼æºé¡¹ç®æä¾(ä¾å¦Commons Logging ç¨æ¥åææçæ¥å¿è¾åºï¼æCommons DBCPç¨æ¥ä½æ°æ®è¿æ¥æ± ),æç±ä½ çåºç¨ç¨åºæå¡å¨æä¾ãå 为åæ ·ççåå ï¼æ们没ææä¾O/R mappingå±ï¼å¯¹æ¤ï¼å·²ææ好ç解å³åæ³å¦HibernateåJDOã Springçç®æ æ¯ä½¿å·²åå¨çææ¯æ´å æç¨ãä¾å¦,尽管æ们没æåºå±äºå¡åè°å¤çï¼ä½æ们æä¾äºä¸ä¸ªæ½è±¡å±è¦çäºJTAæä»»ä½å ¶ä»çäºå¡çç¥ã Spring没æç´æ¥åå ¶ä»çå¼æºé¡¹ç®ç«äºï¼é¤éæ们æå°æ们è½æä¾æ°çä¸äºä¸è¥¿ãä¾å¦ï¼è±¡è®¸å¤å¼å人åï¼æ们ä»æ¥æ²¡æ为Strutsé«å ´è¿ï¼å¹¶ä¸æå°å¨MVC web frameworkä¸è¿ææ¹è¿çä½å°ãå¨æäºé¢åï¼ä¾å¦è½»é级çIoC容å¨åAOPæ¡æ¶ï¼Springæç´æ¥çç«äºï¼ä½æ¯å¨è¿äºé¢åè¿æ²¡æå·²ç»è¾ä¸ºæµè¡ç解å³æ¹æ¡ã(Springå¨è¿äºåºåæ¯å¼è·¯å éã) Springä¹å¾çäºå å¨çä¸è´æ§ã ææçå¼åè é½å¨å±åæ ·ççèµæ,åºç¡æ³æ³ä¾ç¶æ¯Expert One-on-One J2EE设计ä¸å¼åçé£äºã 并ä¸æ们已ç»è½å¤ä½¿ç¨ä¸äºä¸»è¦çæ¦å¿µ,ä¾å¦åç½®æ§å¶ï¼æ¥å¤çå¤ä¸ªé¢åã Springå¨åºç¨æå¡å¨ä¹é´æ¯å¯ç§»æ¤çã å½ç¶ä¿è¯å¯ç§»æ¤æ§æ»æ¯ä¸æ¬¡ææï¼ä½æ¯æ们é¿å ä»»ä½ç¹å®å¹³å°æéæ åå,并ä¸æ¯æå¨WebLogicï¼Tomcatï¼Resinï¼JBossï¼WebSphereåå ¶ä»çåºç¨æå¡å¨ä¸çç¨æ·ã åç½®æ§å¶å®¹å¨ Springçè®¾è®¡æ ¸å¿æ¯ org.springframework.beans å , 为ä¸JavaBeansä¸èµ·å·¥ä½è设计ã è¿ä¸ªå ä¸è¬ä¸ç´æ¥è¢«ç¨æ·ä½¿ç¨, ä½ä½ä¸ºåºç¡ä¸ºæ´å¤çå ¶ä»åè½æå¡. ä¸ä¸ä¸ªè¾é«å±é¢çæ½è±¡æ¯"Bean Factory"ã Spring bean factory æ¯ä¸ä¸ªæ®éçFactoryï¼å®ä½¿å¯¹è±¡è½å¤æå称è·åï¼å¹¶ä¸è½ç®¡ç对象ä¹é´çå ³ç³»ã Bean factories æ¯æ两ç§å¯¹è±¡æ¨¡å¼: . Singletonï¼å¨æ¤æ¨¡å¼ä¸ï¼æä¸ä¸ªå ·æç¹å®å称çå ±äº«å¯¹è±¡å®ä¾ï¼å®å¨æ¥æ¾æ¶è¢«è·åãè¿æ¯é»è®¤çï¼èä¸æ¯æ为ç»å¸¸ä½¿ç¨çãå®å¯¹äºæ ç¶æ对象æ¯ä¸ç§çæ³ç模å¼ã .Prototypeï¼å¨æ¤æ¨¡å¼ä¸ï¼æ¯æ¬¡è·åå°å建ä¸ä¸ªç¬ç«ç对象ãä¾å¦ï¼è¿å¯ä»¥è¢«ç¨äºå 许ç¨æ·æ¥æä»ä»¬èªå·±ç对象ã ç±äº org.springframwork.beans.factory.BeanFactoryæ¯ä¸ä¸ªç®åçæ¥å£ï¼å®è½è¢«ä¸ºäºåºå±åå¨æ¹æ³èå®ç°ãä½ è½å¤æ¹ä¾¿å°å®ç°ä½ èªå·±çBeanFactoryï¼å°½ç®¡å¾å°ç¨æ·éè¦ãæ为常ç¨çå®ä¹æ¯ï¼ .XmlBeanFactoryï¼ å¯è§£æç®åç´è§çå®ä¹ç±»åå½å对象å±æ§çXMLç»æã æ们æä¾äºä¸ä¸ªDTDæ¥ä½¿ç¼åæ´å®¹æã .ListableBeanFactoryImplï¼å¯æä¾è§£æåæ¾å¨å±æ§æ件ä¸çbeanå®ä¹ï¼åå¯éè¿ç¼ç¨å建BeanFactoriesã æ¯ä¸ªbeanå®ä¹å¯è½æ¯ä¸ä¸ªPOJO(éè¿ç±»ååJavaBeanåå§å±æ§å®ä¹)ï¼ææ¯ä¸ä¸ªFactoryBeanãFactoryBeanæ¥å£æ·»å äºä¸ä¸ªé´æ¥å±ãé常ï¼è¿ç¨äºä½¿ç¨AOPæå ¶ä»æ¹æ³æ¥å建代ç对象ï¼ä¾å¦ï¼æ·»å äºå£°ææ§äºå¡ç®¡çç代çã(è¿å¨æ¦å¿µä¸åEJB侦å¬ç¸ä¼¼ï¼ä½å¨å®è·µä¸å®ç°æ´ç®åã) BeanFactoriesè½å¨ä¸ä¸ªå±æ¬¡ç»æä¸å¯éæ©æ§çåä¸ï¼æ ¹æ®æ¥èªç¥å ç继æ¿å®ä¹ãè¿ä½¿å¨æ´ä¸ªåºç¨ä¸å ¬å ±é ç½®çå ±äº«æ为å¯è½ï¼è½ç¶ä¸ªå«èµæºï¼å¦controller servletsï¼ä¹æ¥æä»ä»¬èªå·±çç¬ç«ç对象éåã è¿ç§ä½¿ç¨JavaBeansçå¨æºå¨ç第åç« ä¸ææè¿°ï¼å¨TheServerSideç½ç«ä¸çæå è´¹çPDF(). éè¿BeanFactoryæ¦å¿µï¼Springæ为ä¸ä¸ªåç½®æ§å¶ç容å¨ã(æé常ä¸å欢containerè¿ä¸ªæ¯è¯ï¼å 为å®ä½¿äººèæ³å°éé级容å¨ï¼å¦EJB容å¨ãSpringçBeanFactoryæ¯ä¸ä¸ªå¯éè¿ä¸è¡ä»£ç å建ç容å¨ï¼å¹¶ä¸ä¸éè¦ç¹æ®çé¨ç½²æ¥éª¤ã) ä½äºåç½®æ§å¶èåçæ¦å¿µæ¯å¨Hollywoodååä¸ç»å¸¸è¡¨è¿°ï¼"Donât call me, Iâll call you." IoCå°æ§å¶èè´£æ¬è¿äºæ¡æ¶ä¸ï¼å¹¶è±ç¦»åºç¨ä»£ç ãæ¶åå°é ç½®çå°æ¹ï¼æææ¯è¯´å¨ä¼ ç»ç容å¨ä½ç³»ç»æä¸ï¼å¦EJBï¼ä¸ä¸ªç»ä»¶å¯ä»¥è°ç¨å®¹å¨å¹¶é®âæéè¦å®ç»æåå·¥ä½ç对象Xå¨åªé?âï¼ä½¿ç¨IoC容å¨ååªéæåºç»ä»¶éè¦X对象ï¼å¨è¿è¡æ¶å®¹å¨ä¼æä¾ç»å®ã容å¨åºäºæ¹æ³åä½åºè¿ç§è¯´æï¼æå¯è½æ ¹æ®é ç½®æ°æ®å¦XMLã åç½®æ§å¶çå 个éè¦å¥½å¤ãå¦ï¼ . å 为ç»ä»¶ä¸éè¦å¨è¿è¡æ¶é´å¯»æ¾åä½è ï¼æ以ä»ä»¬å¯ä»¥æ´ç®åçç¼ååç»´æ¤ãå¨SpringçIoCçæ¬éï¼ç»ä»¶éè¿æ´é²JavaBeançsetteræ¹æ³è¡¨è¾¾ä»ä»¬ä¾èµçå ¶ä»ç»ä»¶ãè¿ç¸å½äºEJBéè¿JNDIæ¥æ¥æ¾ï¼EJBæ¥æ¾éè¦å¼å人åç¼å代ç ã . åæ ·åå ï¼åºç¨ä»£ç æ´å®¹ææµè¯ãJavaBeanå±æ§æ¯ç®åçï¼Javaæ ¸å¿çï¼å¹¶ä¸å®¹ææµè¯ï¼ä» ç¼åä¸ä¸ªå å«èªèº«çJunitæµè¯æ¹æ³ç¨æ¥å建对象å设置ç¸å ³å±æ§å³å¯ã . ä¸ä¸ªå¥½çIoCå®ç°éèäºå¼ºç±»åãå¦æä½ ä½¿ç¨ä¸ä¸ªæ®éçfactoryæ¥å¯»æ¾åä½è ï¼ä½ å¿ é¡»éè¿ç±»å转æ¢å°è¿åç»æ转å为æ³è¦çç±»åãè¿ä¸æ¯ä¸ä¸ªä¸»è¦é®é¢ï¼ä½æ¯ä¸é è§ã使ç¨IoCï¼ä½ å¨ä½ ç代ç ä¸è¡¨è¾¾å¼ºç±»åä¾èµï¼æ¡æ¶å°è´è´£ç±»å转æ¢ãè¿æå³çå¨æ¡æ¶é ç½®åºç¨æ¶ï¼ç±»åä¸å¹é å°å¯¼è´é误ï¼å¨ä½ ç代ç ä¸ï¼ä½ æ éæ å¿ç±»å转æ¢å¼å¸¸ã . 大é¨åä¸å¡å¯¹è±¡ä¸ä¾èµäºIoC容å¨çAPIsãè¿ä½¿å¾å¾å®¹æ使ç¨éçä¸æ¥ç代ç ï¼ä¸å¾å®¹æç使ç¨å¯¹è±¡æ 论å¨å®¹å¨å æä¸å¨å®¹å¨å ãä¾å¦ï¼Springç¨æ·ç»å¸¸é ç½®Jakarta Commons DBCPæ°æ®æºä¸ºä¸ä¸ªSpring beanï¼ä¸éè¦äºä»»ä½å®å¶ä»£ç å»åè¿ä»¶äºãæ们说ä¸ä¸ªIoC容å¨ä¸æ¯ä¾µå ¥æ§çï¼ä½¿ç¨å®å¹¶ä¸ä¼ä½¿ä½ ç代ç ä¾èµäºå®çAPIsãä»»ä½JavaBenaå¨Spring bean factoryä¸é½è½æ为ä¸ä¸ªç»ä»¶ã æååºè¯¥å¼ºè°çæ¯ï¼IoC ä¸åäºä¼ ç»ç容å¨çä½ç³»ç»æ( å¦EJB), åºç¨ä»£ç æå°ç¨åº¦çä¾é äºå®¹å¨ãè¿æå³çä½ çä¸å¡å¯¹è±¡å¯ä»¥æ½å¨ç被è¿è¡å¨ä¸åçIoC æ¡æ¶ä¸-æè å¨ä»»ä½æ¡æ¶ä¹å¤-ä¸éè¦ä»»ä½ä»£ç æ¹ã 以æçç»éªåä½ä¸ºSpringç¨æ·ï¼è¿å强è°IoCç»åºç¨ä»£ç 带æ¥ç好å¤æ¯ä¸å®¹æçã IoCä¸æ¯ä¸ä¸ªæ°æ¦å¿µï¼ä½æ¯å®å¨J2EEå¢ä½éé¢ååå°è¾¾é»éæ¶é´ã æä¸äºå¯ä¾éæ©çIoC 容å¨: notably, Apache Avalon, PicoContainer å HiveMind. Avalon ä¸ä¼æ为ç¹å«æµè¡çï¼å°½ç®¡å®å¾å¼ºå¤§èä¸æå¾é¿çåå²ãAvalonæ¯ç¸å½çéé级åå¤æçï¼å¹¶ä¸çèµ·æ¥æ¯æ°çIoC解å³æ¹æ¡æ´å ·ä¾µå ¥æ§ã PicoContaineræ¯ä¸ä¸ªè½»é级èä¸æ´å¼ºè°éè¿æé å¨è¡¨è¾¾ä¾èµæ§èä¸æ¯JavaBean å±æ§ã
springçç»ä»¶åä½ç¨(springclouç»ä»¶)
ç®è¦è¯´æspringçä¸¤ä¸ªæ ¸å¿åè½åå ¶ä½ç¨
springæ¡æ¶æ¯ä¸ä¸ªè½»é级çå¼æºä»ä¼æ¡æ¶ï¼æ¯ä¸ä¸ªIOCåAOP容å¨ãå®æ¯ä½ä¾µå ¥å¼è®¾è®¡ï¼ç¬ç«äºåç§åºç¨æå¡å¨ï¼
ä¾èµæ³¨å ¥çç¹ç¹å°ç»ä»¶å ³ç³»éæåï¼éä½è¦å度
æ§å¶å转ï¼IOCï¼ï¼ç¨æ¥éä½ç¨åºä»£ç ä¹é´çè¦å度ï¼ä½¿æ´ä¸ªç¨åºä½ç³»ç»ææ´å çµæ´»ï¼åæ¶å°ç±»çå建åä¾èµå ³ç³»åå¨é ç½®æ件éï¼ç±é ç½®æä»¶æ³¨å ¥ï¼è¾¾å°æ¾è¦åçææã
DIï¼ä¾èµæ³¨å ¥ï¼
设å¼æ³¨å ¥ï¼åºå±å®ç°setæ¹æ³èµå¼ã
使ç¨æé å¨æ³¨å ¥ï¼ç½©å³åºå±å®ç°æé æ¹æ³æ³¨å ¥ï¼æ ¹æ®beanä¸çåæ°ç±»åååæ°æ°éï¼å¯»æ¾å¯¹åºçæé æ¹æ³ã
èªå¨è£ é ï¼ä¸è½èªå¨è£ é æè°çç®åç±»åå æ¬åºæ¬ç±»åï¼å符串åéåç±»é常ç¨æ¥èªå¨è£ é 对象
æç §å称æ¥èªå¨è£ é åºå±å®ç°æ¯setæ¹æ³
æç §ç±»åæ¥èªå¨è£ é åºå±å®ç°æ¯setæ¹æ³
2.é¢ååé¢ç¼ç¨ï¼AOPï¼
æ主è¦çä½ç¨ï¼å¯ä»¥å¨ä¸ä¿®æ¹æºä»£ç çæ åµä¸ï¼ç»ç®æ æ¹æ³å¨ææ·»å åè½
ä¸å¡é»è¾å°±ä¸å¿çå¤çå®é éæ±ï¼éç¨çå¢å¼ºåè½ç¬ç«åºæ¥ãå°å®å ¨äºå¡çç¨åºé»è¾ç¸å¯¹ç¬ç«çåè½æ½ååºæ¥ï¼å©ç¨Springçé ç½®æ件å°è¿äºåè½æè¿å»ï¼å®ç°äºæç §åé¢ç¼ç¨ï¼æé«äºå¤ç¨æ§ã
åç§å¢å¼ºæ¹å¼ï¼
åç½®å¢å¼ºï¼å¨æ ¸å¿åè½ä¹åæ§è¡çé¢å¤åè½
åç½®å¢å¼ºï¼å¨æ ¸ç©ææ å¿åè½ä¹åæ§è¡çé¢å¤åè½
å¼å¸¸å¢å¼ºï¼å¨æ ¸å¿åè½åçå¼å¸¸æ¶æ§è¡çé¢å¤åè½
ç¯ç»å¢å¼ºï¼å¨æ ¸å¿åè½ä¹å以åä¹åæ§è¡çé¢å¤åè½
springå å«åªäºç»ä»¶
Springæ¡æ¶æ¯ä¸ä¸ªåå±æ¶æï¼ç±7个å®ä¹è¯å¥½ç模åç»æè¢å¤ãSpring模åæ建å¨æ ¸å¿å®¹å¨ä¹ä¸ï¼æ ¸å¿å®¹å¨ç«å®´å®ä¹äºå建ãé ç½®å管çbeançæ¹å¼ï¼ç»æSpringæ¡æ¶çæ¯ä¸ªæ¨¡åï¼æç»ä»¶ï¼é½å¯ä»¥åç¬åå纤æ¹å¨ï¼æè ä¸å ¶ä»ä¸ä¸ªæå¤ä¸ªæ¨¡åèåå®ç°ã
SpringMVC主è¦ç»ä»¶è¯´æ1ãå端æ§å¶å¨DispatcherServletï¼ä¸éè¦å¼åï¼ç±æ¡æ¶æä¾ãæ ¸å¿ãï¼
DispatcherServletæ¯SpringMVCçå ¥å£å½æ°ãæ¥æ¶è¯·æ±ï¼ååºç»æï¼ç¸å½äºè½¬åå¨ç¢§ç®ï¼ä¸å¤®å¤çå¨ãæäºDispatcherServletï¼å¯ä»¥å¤§å¤§åå°å ¶å®ç»ä»¶ä¹é´çè¦å度ã
ç¨æ·è¯·æ±å°è¾¾å端æ§å¶å¨ï¼å°±ç¸å½äºmvc模å¼ä¸çcï¼DispatcherServletæ¯æ´ä¸ªæµç¨æ§å¶çä¸å¿ï¼ç±å®è°ç¨å ¶å®ç»ä»¶æ¥å¤çç¨æ·ç请æ±ã
2ãå¤çå¨æ å°å¨HandlerMapping(ä¸éè¦å¼åï¼ç±æ¡æ¶æä¾)
HandlerMappingè´è´£æ ¹æ®ç¨æ·è¯·æ±ï¼URLï¼ï¼æ¾å°ç¸åºçHandlerå³å¤çå¨ï¼Controllerï¼ï¼SpringMVCæä¾äºä¸åæ å°å¨å®ç°çä¸åæ å°æ¹å¼ï¼ä¾å¦ï¼é ç½®æ件æ¹å¼ï¼å®ç°æ¥å£æ¹å¼ï¼æ³¨è§£æ¹å¼çã
3ãå¤çå¨éé å¨HandlerAdapter(ä¸éè¦å¼åï¼ç±æ¡æ¶æä¾)
æç §ç¹å®è§åï¼HandlerAdapterè¦æ±çè§åï¼å»æ§è¡Handlerï¼éè¿HandlerAdapter对å¤çå¨è¿è¡æ§è¡ï¼è¿æ¯éé å¨æ¨¡å¼çåºç¨ï¼éè¿æ©å±éé å¨å¯ä»¥å¯¹æ´å¤ç±»åçå¤çå¨è¿è¡å¤çã
4ãå¤çå¨Handler(éè¦å·¥ç¨å¸å¼å)
Handleræ¯ç»§DispatcherServletå端æ§å¶å¨çå端æ§å¶å¨ï¼å¨DispatcherServletçæ§å¶ä¸ï¼Handlerå¯¹å ·ä½çç¨æ·è¯·æ±è¿è¡å¤çãç±äºHandleræ¶åå°å ·ä½çç¨æ·ä¸å¡è¯·æ±ï¼æ以ä¸è¬æ åµä¸éè¦å·¥ç¨å¸æ ¹æ®ä¸å¡éæ±æ¥å¼åHandlerã
5ãè§å¾è§£æå¨ViewResolver(ä¸éè¦å¼åï¼ç±æ¡æ¶æä¾)
ä½ç¨ï¼è¿è¡è§å¾è§£æï¼æ ¹æ®é»è¾è§å¾å解ææçæ£çè§å¾ï¼Viewï¼ï¼ViewResolverè´è´£å°å¤çç»æçæViewè§å¾ãé¦å ï¼æ ¹æ®é»è¾è§å¾å解ææç©çè§å¾åï¼å³å ·ä½ç页é¢å°åï¼ï¼åçæViewè§å¾å¯¹è±¡ï¼æå对Viewè¿è¡æ¸²æï¼å°å¤çç»æéè¿é¡µé¢å±ç¤ºç»ç¨æ·ã
SpringMVCæ¡æ¶æä¾äºå¾å¤çViewè§å¾ç±»åï¼å æ¬ï¼jstlViewãfreemarkerViewãpdfViewçãä¸è¬æ åµä¸ï¼éè¦éè¿é¡µé¢æ ç¾æ页æ¸é®é¢æ¨¡çææ¯ï¼å°æ¨¡åæ°æ®éè¿é¡µé¢å±ç¤ºç»ç¨æ·ï¼è¿éè¦ç±å·¥ç¨å¸æ ¹æ®ä¸æ §å·§ä¸å¡éæ±å¼åå ·ä½ç页é¢ã
6ãè§å¾View(éè¦å·¥ç¨å¸å¼å)
Viewæ¯ä¸ä¸ªæ¥å£ï¼å®ç°ç±»æå¯ä»¥æ¯æä¸åçViewç±»åï¼jspãfreemarkerãpdf...ï¼
æ»ç»ï¼å¤çå¨Handlerï¼ä¹å°±æ¯å¹³å¸¸è¯´çControlleræ§å¶å¨ï¼ä»¥åè§å¾å±Viewï¼é½æ¯éè¦èªè¡å¼åçãå ¶ä»çä¸äºç»ä»¶ï¼å¦ï¼å端æ§å¶å¨DispatcherServletãå¤çå¨æ å°å¨HandlerMappingãå¤çå¨éé å¨HandlerAdapterçé½æ¯ç±æ¡æ¶æä¾ã
spring主è¦çä½ç¨ï¼Springæ¡æ¶æ¯ä¸ºäºè§£å³ä¼ä¸åºç¨å¼åçå¤ææ§èå建çã
Springçç¨éä¸ä» ä» éäºæå¡å¨ç«¯çå¼åãä»ç®åæ§ãå¯æµè¯æ§åæ¾è¦åæ§è§åº¦èè¨ï¼ç»å¤§é¨åJavaåºç¨é½å¯ä»¥ä»Springä¸åçã使ç¨åºæ¬çJavaBean代æ¿EJBï¼å¹¶æä¾äºæ´å¤çä¼ä¸åºç¨åè½ã
æ©å±èµæ
ä¼ç¹
1ãJAVAEEåºè¯¥æ´å 容æ使ç¨ã
2ãé¢å对象ç设计æ¯ä»»ä½å®ç°ææ¯ï¼æ¯å¦JAVAEEï¼é½éè¦ã
3ãé¢åæ¥å£ç¼ç¨ï¼èä¸æ¯é对类ç¼ç¨ãSpringå°ä½¿ç¨æ¥å£çå¤æ度éä½å°é¶ãï¼é¢åæ¥å£ç¼ç¨æåªäºå¤æ度ï¼
4ã代ç åºè¯¥æäºæµè¯ãSpringæ¡æ¶ä¼å¸®å©ä½ ï¼ä½¿ä»£ç çæµè¯å¤è¡¡æ´å ç®åã
5ãJavaBeanæä¾äºåºç¨ç¨åºé ç½®çæ好æ¹æ³ã
6ãå¨Javaä¸ï¼å·²æ£æ¥å¼å¸¸ï¼Checkedexceptionï¼è¢«è¿åº¦ä½¿ç¨ãæ¡æ¶ä¸åºè¯¥è¿«ä½¿ä½ ææ碧è·ä¸æè´ºåè½æ¢å¤çå¼å¸¸ã
åèèµææ¥æºï¼ç¾åº¦ç¾ç§-springæ¡æ¶