spring in action 第一章

spring in action 第一章

spring是从何而来?

spring是为了解决企业级应用开发的复杂性而创建的,使用spring可以让简单的javaBeans实现以前EJB才能完成的事情。而且spring不仅仅局限于服务器端开发,任何java应用都能在简单性,可测试性和松耦合性等方面从spring中获益。spring可以做很多事情。但归根结底,支撑spring的仅仅是少许的基本理念,所有的理念都可以追溯到spring的的最根本使命上:简化java开发。
降低java开发的复杂性,spring采取了以下四个策略:
1.基于POJO(简单java类)的轻量级和最小侵入性编程
2.通过依赖注入和面向接口实现松耦合
3.基于切面和惯例进行声明式编程
4.通过切面和模板减少样板式代码

1简化java开发

1.1激发pojo潜能

在以前的框架中我们的程序或许会被他们的规则焊死。而spring尽力避免自身api弄乱我们的代码。spring不会强迫你你实现spring规范的接口或者继承spring规范的类,相反,在基于spring构建的应用中,它的类通常没有任何痕迹表明你使用了spring。最坏的场景是,一个类或许会使用spring注解,但它仍然是POJO(简单java类)
在这里插入图片描述
就像是上图的样子,在HelloWorldBean上没有任何过分的要求。这就是一个POJO(简单Java类),没有任何证据表明它是一个spring组件。spring的非侵入编程模型意味着这个类在spring应用和非spring应用中都可以发挥同样的作用。

监管POJO看起来很简单,但spring可以通过DI(依赖注入)来装配它们。让我们看看DI是如何帮助应用对象之间保持松耦合的。

1.2依赖注入

依赖注入看起来一个nb plus的词语,现在也已经演变成为一项复杂的编程技巧或设计模式理念。其实依赖注入并不像听上去那样复杂。在项目中应用DI,你会发现你的代码会变得异常简单而且更加容易理解和测试。

任何一个项目都会有两个或者更多的类组成,这些类相互协作完成特定的业务逻辑。按照一贯做法,每个对象负责管理与自己相互协作的对象的引用,这将会导致高度耦合和难以测试的代码。
在这里插入图片描述
如上DamselResuingKnight只能执行DamselResuingQuest的探险任务。这两个类之间的耦合度太高了,以至于少女守护者只能做很单一的任务,他能随时保护女孩但是如果要去杀掉恶龙或者给女孩打饭呢,那这个守护者是做不到这些的。

更糟糕的是为这个类编写单元测试出奇的困难,编写测试我们要保证守护者被召唤来的时候他的方法会被调用,没有简单明了的方法可以实现这一点。

耦合具有两面性。一方面,紧密耦合的代码难以测试,难以复用,难以理解,并且典型的表现出“打地鼠”式的bug特性(修复一个bug会有更多bug出现)。另一方面耦合是不可避免的,为了完成特定任务总有类在交互,所以我们应该谨慎管理耦合。

通过DI,对象的依赖关系由系统中的第三方组件在创建对象的时候进行设定,对象无需创建或者管理它们的依赖关系。
在这里插入图片描述
如上图这次我们传入一个quest他不是一个具体的探险任务,而是一个任务接口,只要实现了这个接口的探险任务BraveKnight都可以胜任。这样BraveKnight没有和任何特定探险任务有耦合,这就是DI的最大收益松耦合。

我们为BraveKnight编写一个测试是很轻松地,只需给quest一个mock实现即可
在这里插入图片描述
知道了spring松耦合的原理那么我们该注入quest了有下图一个杀龙的探险任务
在这里插入图片描述
可以看到这个类实现了Quest接口那么它可以注入BraveKnight,我们不仅要把这个类注入到BraveKnight里,而且要把stream注入到这个类里面。spring将创建组件之间的协作行为称为装配(wiring)。spring多种装配方式,第一种xml文件
在这里插入图片描述
第二种java配置
在这里插入图片描述
两种带来的DI收益是一样的,并且它们都符合上面的松耦合规则,被装配对象不知道要装配什么具体的对象,但是这些对象都有相同的接口,在装配时才知道是什么类型。

接下来要使用装配好的对象,这时需要spring应用上下文,它全权负责对象的创建和组装。spring有多种应用上下文,这里选择ClassPathXmlApplicationContext这个类加载类路径下的一个或多个xml文件,如下图
在这里插入图片描述
这里可以看出来我们不知道knight的具体细节只有xml文件知道,我们不知道谁在执行任务,更不知道在执行什么样的任务。

1.3应用切面(这里大都引用原文,原文很清晰)

DI能够保证对象之间的松耦合,而面向切面允许编程允许把遍布在各处的功能分离出可重用组件

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
的理念
例子见原文这里理解原理即可

1.4使用模板消除样板式代码

有时我们会将一些代码一遍又一遍得写,比如JDBC的代码如图
在这里插入图片描述
在这里插入图片描述
下面是spring jdbcTemplate的代码
在这里插入图片描述
模板代码可以让你只关注代码自身的职责。
在这里插入图片描述

2.容纳你的bean

在spring应用中,你的应用对象生存于spring容器中,spring容器负责创建对象并且装配它们,配置和管理它们的整个生命周期,从创建到死亡(从new 到 finalize)
在这里插入图片描述
在这里插入图片描述

2.1使用上下文

在这里插入图片描述
这里不谈web应用,剩余的上下文使用方法如下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最后我们只需要用getBean方法获取类就可以了

2.1bean的生命周期

一般的java bean生命周期从new开始一直到没有引用的时候会被垃圾回收机制自动回收

相比而言spring bean生命周期要复杂得多,正确理解spring bean 生命周期非常重要,因为你或许要利用spring提供的扩展点来自定义bean的创建过程。下图展示了bean装载到spring上下文中的一个完整的生命周期过程
在这里插入图片描述
在这里插入图片描述
spring的功能很强大,上面所述的DI AOP 和消除版样式代码只是spring的简化java开发的基本功能,它还有许多超乎想象的功能。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 第一部分spring的核心 第1章开始spring之旅 1.1spring是什么 1.2开始spring之旅 1.3理解依赖注入 1.3.1依赖注入 1.3.2di应用 1.3.3企业级应用中的依赖注入 1.4应用aop 1.4.1aop介绍 1.4.2aop使用 1.5小结 第2章基本bean装配 2.1容纳你的bean 2.1.1beanfactory介绍 2.1.2使用应用上下文 2.1.3bean的生命 2.2创建bean 2.2.1声明一个简单的bean 2.2.2通过构造函数注入 2.3注入bean属性 2.3.1注入简单的数值 2.3.2使用其他的bean 2.3.3装配集合 2.3.4装配空值 2.4自动装配 2.4.1四种自动装配类型 2.4.2混合使用自动和手动装配 2.4.3何时采用自动装配 2.5控制bean创建 2.5.1bean范围化 2.5.2利用工厂方法来创建bean 2.5.3初始化和销毁bean 2.6小结 第3章高级bean装配 3.1声明父bean和子bean 3.1.1抽象基bean类型 3.1.2抽象共同属性 3.2方法注入 3.2.1基本的方法替换 3.2.2获取器注入 3.3注入非springbean 3.4注册自定义属性编辑器 3.5使用spring的特殊bean 3.5.1后处理bean 3.5.2bean工厂的后处理 3.5.3配置属性的外在化 3.5.4提取文本消息 3.5.5程序事件的解耦 3.5.6让bean了解容器 3.6脚本化的bean 3.6.1给椰子上lime 3.6.2脚本化bean 3.6.3注入脚本化bean的属性 3.6.4刷新脚本化bean 3.6.5编写内嵌的脚本化bean 3.7小结 第4章通知bean 4.1aop简介 4.1.1定义aop术语 4.1.2spring对aop的支持 4.2创建典型的spring切面 4.2.1创建通知 4.2.2定义切点和通知者 4.2.3使用proxyfactorybean 4.3自动代理 4.3.1为spring切面创建自动代理 4.3.2自动代理@aspectj切面 4.4定义纯粹的pojo切面 4.5注入aspectj切面 4.6小结 第二部分企业spring 第5章使用数据库 5.1spring的数据访问哲学 5.1.1了解spring数据访问的异常体系 5.1.2数据访问的模板化 5.1.3使用dao支持类 5.2配置数据源 5.2.1使用jndi数据源 5.2.2使用数据源连接池 5.2.3基于jdbc驱动的数据源 5.3在spring里使用jdbc 5.3.1处理失控的jdbc代码 5.3.2使用jdbc模板 5.3.3使用spring对jdbc的dao支持类 5.4在spring里集成hibernate 5.4.1选择hibernate的版本 5.4.2使用hibernate模板 5.4.3建立基于hibernate的dao 5.4.4使用hibernate3上下文会话 5.5spring和java持久api 5.5.1使用jpa模板 5.5.2创建一个实体管理器工厂 5.5.3建立使用jpa的dao 5.6spring和ibatis 5.6.1配置ibatis客户模板 5.6.2建立基于ibatis的dao 5.7缓存 5.7.1配置缓存方案 5.7.2缓存的代理bean 5.7.3注解驱动的缓存 5.8小结 第6章事务管理 6.1理解事务 6.1.1仅用4个词解释事务 6.1.2理解spring对事务管理的支持 6.2选择事务管理器 6.2.1jdbc事务 6.2.2hibernate事务 6.2.3jpa事务 6.2.4jdo事务 6.2.5jta事务 6.3在spring中编写事务 6.4声明式事务 6.4.1定义事务参数 6.4.2代理事务 6.4.3在spring2.0里声明事务 6.4.4定义注释驱动事务 6.5小结 第7章保护spring 7.1springsecurity介绍 7.2验证用户身份 7.2.1配置providermanager 7.2.2根据数据库验证身份 7.2.3根据ldap仓库进行身份验证 7.3控制访问 7.3.1访问决策投票 7.3.2决定如何投票 7.3.3处理投票弃权 7.4保护web应用程序 7.4.1代理springsecurity的过滤器 7.4.2处理安全上下文 7.4.3

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值