Spring4实战读书笔记

Spring4实战读书笔记

首先,我们需要明白,为什么我们需要引入Spring,也就是说Spring的好处。个人觉得主要是在于两方面解耦和对bean的管理。

第一部分:Spring核心

共分为四个章节:

在这里插入图片描述

第一章节:Spring之旅

相当于对整个Spring框架进行了整体概括,如

  1. spring的容器
  2. spring的核心模块
  3. spring的生态系统
  4. spring的新功能

Spring是如何简化我们开发的

  1. DI (依赖注入 dependency injection)
  2. AOP(面向切面编程 aspect- oriented programming)
  3. 使用模板消除样板式代码
依赖注入(DI)

什么是DI(dependency injection)

来源于百度百科:

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中 。

代码演示:

@RunWith( SpringJUnit4ClassRunner. class)
@ContextConfiguration( classes= AspectConfig.class)
public class TestMain {
    @Autowired
    private Performance performance;

    @Test
    public void testOne(){
        System.out.println(performance);
        performance.perform();
    }
}

通俗点说:当我们依赖某一个类的时候不再去手动new创建对象,而是通过Spring来帮我们创建。

面向切面编程(AOP)

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

总结:DI能够让相互协作的软件组件保持松散耦合,而面向切面编程( aspect- oriented programming, AOP) 允许你把遍布应用各处的功能分离出来形成可重用的组件。

样板式代码

Spring旨在通过模板封装来消除样板式代码。 如Spring对jdbc的链接操作做的 JdbcTemplate 封装,其他的还有诸如Redis,JMS,MongoDB等等。

Spring容器

在 基于 Spring 的 应用 中, 你的 应用 对象 生 存于 Spring 容器( container) 中。 如图 1. 4 所示, Spring 容器 负责 创建 对象, 装配 它们, 配置 它们 并 管理 它们 的 整个 生命 周期, 从 生存 到 死亡( 在这里, 可能 就是 new 到 finalize())。

在这里插入图片描述

Spring容器分类:

Bean工厂: 由 org. springframework. beans. factory. BeanFactory 接口 定义, 是最 简单 的 容器, 提供 基本 的 DI 支持。

应用上下文: 由 org. springframework. context. ApplicationContext 接口 定义, 基于 BeanFactory 构建, 并提 供应 用 框架 级别 的 服务, 例如 从属 性 文件 解析 文本 信息 以及 发布 应用 事件 给 感兴趣 的 事件 监听 者。

Spring自带了多种类型的应用上下文

AnnotationConfigApplicationContext: 从 一个 或 多个 基于 Java 的 配置 类 中 加载 Spring 应用 上下文。

AnnotationConfigWebApplicationContext: 从 一个 或 多个 基于 Java 的 配置 类 中 加载 Spring Web 应用 上下文。

ClassPathXmlApplicationContext: 从 类 路径 下 的 一个 或 多个 XML 配置文件 中 加载 上下文 定义, 把 应用 上下文 的 定义 文件 作为 类 资源。

FileSystemXmlapplicationcontext: 从文 件 系统 下 的 一个 或 多个 XML 配置文件 中 加载 上下文 定义。

XmlWebApplicationContext: 从 Web 应用 下 的 一个 或 多个 XML 配置文件 中 加载 上下文 定义。

bean的生命周期

传统bean的生命周期:

在 传统 的 Java 应用 中, bean 的 生命 周期 很 简单。 使用 Java 关键字 new 进行 bean 实例 化, 然后 该 bean 就可 以使 用了。 一旦 该 bean 不再 被 使用, 则由 Java 自动 进行 垃圾 回收。

Spring的bean的生命周期

在这里插入图片描述

Spring模块

在这里插入图片描述

Spring模块-Spring核心容器

容器 是 Spring 框架 最 核心 的 部分, 它 管理 着 Spring 应用 中 bean 的 创建、 配置 和 管理。 在 该 模块 中, 包括了 Spring bean 工厂, 它为 Spring 提供 了 DI 的 功能。 基于 bean 工厂, 我们 还会 发现 有 多种 Spring 应用 上下文 的 实现, 每一种 都 提供 了 配置 Spring 的 不同 方式。 除了 bean 工厂 和 应用 上下文, 该 模块 也 提供 了 许多 企业 服务, 例如 E- mail、 JNDI 访问、 EJB 集成 和 调度。 所有 的 Spring 模块 都 构建 于 核心 容器 之上。 当你 配置 应用 时, 其实 你 隐式 地 使用 了 这些 类。

Spring模块-Spring的AOP模块

在 AOP 模块 中, Spring 对面 向 切面 编程 提供 了 丰富 的 支持。 这个 模块 是 Spring 应用 系统 中 开发 切面 的 基础。 与 DI 一样, AOP 可以 帮助 应用 对象 解 耦。 借助于 AOP, 可以 将 遍布 系统 的 关注 点( 例如 事务 和 安全) 从 它们 所 应用 的 对象 中 解 耦 出来。

Spring模块-数据访问与集成

对于各种通用样板式代码进行了封装。对常用第三方服务进行了整合,如JMS,Redis

Spring模块-Web与远程调用

SpringMvc

Spring模块-Instrumentation

Spring 的 Instrumentation 模块 提供 了 为 JVM 添加 代理( agent) 的 功能。 具体 来讲, 它为 Tomcat 提供 了 一个 织入 代理, 能够 为 Tomcat 传递 类 文件, 就 像 这些 文件 是 被 类 加载 器 加载 的 一样。

Spring模块-测试

鉴于 开发者 自 测 的 重要性, Spring 提供 了 测试 模块 以 致力于 Spring 应用 的 测试。

第二章节:装配Bean

本章内容:

  1. 声明bean
  2. 构造器注入和set方法注入
  3. 装配bean
  4. 控制bean的创建和销毁

当我们实现某个功能当前类还需要引入某种服务并且这种服务是由其他类提供的,这时我们需要创建应用对象和服务对象,而这种实现某种业务功能而创建对象那么这种对象之间的协作关系称之为装配,也是依赖注入的本质。

Spring三种主要的Bean装配机制

在XML中进行显示配置

在JAVA中进行显示配置

隐式bean发现机制和自动装配

通常不限制使用哪种方式,某些极端场景需要多种形式配合才行。

自动化装配bean

自动化装配实际是与xml的显示配置的一种区分,实际效果都是一样的。

实现自动化装配bean的方式:

组件扫描:Spring 会 自动 发现 应用 上下文 中 所 创建 的 bean。

自动装配:Spring 自动 满足 bean 之间 的 依赖。 这里有按类型或按id注入的实现

@Component 注解

这个 简单 的 注解 表明 该类 会 作为 组件 类, 并 告知 Spring 要 为 这个 类 创建 bean。

@ComponentScan 注解

默认 会 扫描 与 配置 类 相同 的包以 及 这个 包 下 的 所有 子 包,与xml的里面的

< context: component- scan base- package=" com.hand" />的效果是一致的。

可以配置同时扫描多个包

为组件扫描的bean命名

Spring 应用 上下 文中 所有 的 bean 都会 给定 一个 ID。就是 将 类 名 的 第一个 字母 变为 小写。 如果 想 为 这个 bean 设置 不同 的 ID, 你 所 要做 的 就是 将 期望 的 ID 作为 值 传递 给@ Component 注解。做法如下:

@Component("audience")
public class Audience {}

Spring 支持 将@ Named 作为@ Component 注解 的 替代 方案。 两者之间 有 一些 细微 的 差异, 但是 在 大多数 场景 中, 它们 是 可以 互相 替换 的。

bean实现自动装配

bean如何实现自动自动装配

自动装配 就是 让 Spring 自动 满足 bean 依赖 的 一种 方法, 在 满足 依赖 的 过程中, 会在 Spring 应用 上下 文中 寻找 匹配 某个 bean 需求 的 其他 bean。 为了 声明 要 进行 自动 装配, 我们 可以 借助 Spring 的@ Autowired 注解。

**值得注意的是:**如果 没有 匹配 的 bean, 那么 在 应用 上下文 创建 的 时候, Spring 会 抛出 一个 异常。 为了 避免 异常 的 出现, 你 可以 将@ Autowired 的 required 属性 设置 为 false:

@RunWith( SpringJUnit4ClassRunner. class)
@ContextConfiguration( classes= AspectConfig.class)
public class TestMain {
    @Autowired(required = false)
    private Performance performance;

    @Test
    public void testOne(){
        System.out.println(performance);
        performance.perform();
    }
}

**自动装配带来的歧义性:**将 required 属性 设置 为 false 时, Spring 会 尝试 执行 自动 装配, 但是 如果 没有 匹配 的 bean 的 话, Spring 将会 让 这个 bean 处于 未 装配 的 状态。 但是, 把 required 属性 设置 为 false 时, 你 需要 谨慎 对待。 如果 在 你的 代码 中 没有 进行 null 检查 的 话, 这个 处于 未 装配 状态 的 属性 有可能 会 出现 NullPointerException。 如果 有 多个 bean 都能 满足 依赖 关系 的 话, Spring 将会 抛出 一个 异常, 表明 没有 明确 指定 要 选择 哪个 bean 进行 自动 装配。

@Inject

@Inject 注解 来源于 Java 依赖 注入 规范, 该 规范 同时 还为 我们 定义 了@ Named 注解。 在 自动 装配 中, Spring 同时 支持@ Inject 和@ Autowired。 尽管@ Inject 和@ Autowired 之间 有着 一些 细微 的 差别, 但是 在 大多数 场景 下, 它们 都是 可以 互相 替换 的。

相对于传统的xml配置方式,Spring支持纯代码的形式进行配置,也就是JavaConfig

@ Configuration

@ Configuration 注解 表明 这个 类 是一 个 配置 类,JavaConfig也是通过它来实现的。

@Bean

@Bean 注解 会 告诉 Spring 这个 方法 将会 返回 一个 对象, 该 对象 要 注册 为 Spring 应用 上下文 中的 bean。 方法 体中 包含 了 最终 产生 bean 实例 的 逻辑。

通过xml形式bean的方式不再赘述,基本上javaConfig都能对xml配置进行代替

第三章节-高级装配

主要内容

  1. Spring profile
  2. 条件化的bean声明
  3. 自动装配与歧义性
  4. bean的作用域
  5. Spring表达式语言
spring profile

spring profile与maven profile的意义某种程度上来说是相同的,这里不做赘述

条件化的bean声明

条件化bean的声明:一个 或 多个 bean 只有 在 应 用的 类 路径 下 包含 特 定的 库 时 才 创建。 或者 我们 希望 某个 bean 只有 当 另外 某个 特定 的 bean 也 声明 了 之后 才会 创建。 我们 还可能 要求 只有 某个 特定 的 环境 变量 设置 之后, 才会 创建 某个 bean。 在 Spring 4 之前, 很难 实现 这种 级别 的 条件 化 配置, 但是 Spring 4 引入 了 一个 新的@ Conditional 注解,可以用来实现这种需求。

自动装配的歧义性:

首先需要明确的是@Autowired是按类型进行的装配

**何时会出现自动装配的歧义性:**仅有 一个 bean 匹配 所需 的 结果 时, 自动 装配 才是 有效 的。 如果不 仅有 一个 bean 能够 匹配 结果 的 话, 这种 歧义 性 会 阻碍 Spring 自动 装配 属性、 构造 器 参数 或 方法 参数,并且会抛出NoUniqueBeanDefinitionException。

如何解决自动装配的歧义性

既然有多个可选,某种程度上来说这多个bean还是存在区别。在spring中可以通过将 可选 bean 中的 某一个 设为 首选( primary) 的 bean, 或者 使用 限定 符( qualifier) 来 帮助 Spring 将 可选 的 bean 的 范围 缩小 到 只有 一个 bean。

@Primary
public class SgtPeppers implements CompactDisc {
}
//或者
@Bean 
@Primary 
public Dessert iceCream() {}

当@Primary仍然不能满足我们的需求时,可以尝试使用@Qualifier

@Autowired 

@Qualifier(" iceCream")

public void setDessert( Dessert dessert) { this. dessert = dessert; }

因为spring不允许一个类里面同一个注解出现多次,当所有能用的注解都用上之后还存在歧义性,这个时候你需要自定义注解了。Java 8 允许 出现 重复 的 注解, 只要 这个 注解 本身 在 定义 的 时候 带有@ Repeatable 注解 就可以。 不过, Spring 的@ Qualifier 注解 并没有 在 定义 时 添加@ Repeatable 注解。

bean的作用域

在 默认 情况下, Spring 应用 上下 文中 所有 bean 都是 作为 以 单 例( singleton) 的 形式 创建 的。 也就是说, 不管 给定 的 一个 bean 被 注入 到 其他 bean 多少 次, 每次 所 注入 的 都是 同一个 实例。

默认是单例的,而对象调用的方法都是会独立开辟空间的。

单 例( Singleton): 在 整个 应用 中, 只 创建 bean 的 一个 实例。

原型( Prototype): 每次 注入 或者 通过 Spring 应用 上下文 获取 的 时候, 都会 创建 一个 新的 bean 实例。

会话( Session): 在 Web 应用 中, 为 每个 会话 创建 一个 bean 实例。

请求( Rquest): 在 Web 应用 中, 为 每个 请求 创建 一个 bean 实例。

单例的实现方式:

@Component

@Scope( ConfigurableBeanFactory. SCOPE_ PROTOTYPE) 

public class Notepad { ... }

第四章节-面向切面的Spring

主要内容:

面向切面编程的基本原理

通过POJO来创建切面

使用@Aspect注解

为AspectJ切面注入依赖

如果 让 应用 对象 只 关注 于 自己 所 针对 的 业务 领域 问题, 而 其他 方面 的 问题 由其 他 应用 对象 来 处理。

横切关注点

在 软件 开发 中, 散布 于 应用 中 多处 的 功能 被称为 横 切 关注 点

简而言之, 横 切 关注 点 可以 被 描述 为 影响 应用 多处 的 功能,而切面可以用来实现横切关注点。

下图的安全就可以称之为横切关注点

在这里插入图片描述

常见实现通用功能的方式:
继承

委托

切面

AOP术语

通知( Advice)

通知 定义 了 切面 是什么 以及 何时 使用。 除了 描述 切面 要 完成 的 工作, 通知 还 解决 了 何时 执行 这个 工作 的 问题。 它 应该 应用 在某 个 方法 被 调用 之前? 之后? 之前 和 之后 都 调用? 还是 只在 方法 抛出 异常 时调 用?

Spring 切面 可以 应用 5 种 类型 的 通知:

前置 通知( Before): 在 目标 方法 被 调用 之前 调用 通知 功能;

后置 通知( After): 在 目标 方法 完成 之后 调用 通知, 此时 不会 关心 方法 的 输出 是什么;

返回 通知( After- returning): 在 目标 方法 成功 执行 之后 调用 通知;

异常 通知( After- throwing): 在 目标 方法 抛出 异常 后 调用 通知;

环绕 通知( Around): 通知 包裹 了 被 通知 的 方法, 在被 通知 的 方法 调用 之前 和 调用 之后 执行 自定义 的 行为。

连接点( Join point)

Craig Walls 沃尔斯. Spring实战(第4版)(异步图书) (Kindle 位置 2864-2865). 人民邮电出版社. Kindle 版本.

连接 点 是在 应用 执行 过程中 能够 插入 切面 的 一个 点。 这个 点 可以 是 调用 方法 时、 抛出 异常 时、 甚至 修改 一个 字段 时。 切面 代码 可以 利用 这些 点 插入 到 应用 的 正常 流程 之中, 并 添加 新的 行为。

切点( Poincut)

切点 的 定义 会 匹配 通知 所要 织入 的 一个 或 多个 连接 点。 我们 通常 使用 明确 的 类 和 方法 名称, 或是 利用 正 则 表达式 定义 所 匹配 的 类 和 方法 名称 来 指定 这些 切点。

切面( Aspect)

切面 是 通知 和 切点 的 结合。 通知 和 切点 共同 定义 了 切面 的 全部 内容—— 它是 什么, 在 何时 和 何处 完成 其 功能。

引入( Introduction)

引入 允许 我们 向 现 有的 类 添加 新方法 或 属性。

织入( Weaving)

织入 是把 切面 应用 到 目标 对象 并 创建 新的 代理 对象 的 过程。 切面 在 指定 的 连 接点 被 织入 到 目标 对象 中。 在 目标 对象 的 生命 周期 里 有 多个 点 可以 进行 织入:

编译 期: 切面 在 目标 类 编译 时 被 织入。 这种 方式 需要 特殊 的 编译器。 AspectJ 的 织入 编译器 就是 以 这种 方式 织入 切面 的。

类 加载 期: 切面 在 目标 类 加载 到 JVM 时 被 织入。 这种 方式 需要 特殊 的 类 加载 器( ClassLoader), 它可 以在 目标 类 被 引入 应用 之前 增强 该 目标 类 的 字节 码。 AspectJ 5 的 加载 时 织入( load- time weaving, LTW) 就 支持 以 这种 方式 织入 切面。

运行 期: 切面 在 应用 运行 的 某个 时刻 被 织入。 一般 情况下, 在 织入 切面 时, AOP 容器 会为 目标 对象 动态 地 创建 一个 代理

Spring实现的切面是变体, Spring AOP 构建 在 动态 代理 基础 之上, 因此, Spring 对 AOP 的 支持 局限于 方法 拦截。

Spring 在 运行时 通知 对象

通过 在 代理 类 中 包裹 切面, Spring 在 运 行期 把 切面 织入 到 Spring 管理 的 bean 中。 如图 4. 3 所示, 代理 类 封装 了 目标 类, 并 拦截 被 通知 方法 的 调用, 再把 调用 转发 给 真正 的 目标 bean。 当代 理 拦截 到 方法 调用 时, 在调 用 目标 bean 方法 之前, 会 执行 切面 逻辑。

在这里插入图片描述

直到 应用 需要 被 代理 的 bean 时, Spring 才 创建 代理 对象。 如果 使 用的 是 ApplicationContext 的 话, 在 ApplicationContext 从 BeanFactory 中 加载 所有 bean 的 时候, Spring 才会 创建 被 代理 的 对象。 因为 Spring 运行时 才 创建 代理 对象, 所以 我们 不需要 特殊 的 编译器 来 织入 Spring AOP 的 切面。

切点表达式

在这里插入图片描述

切面的实现

注解的形式

xml的形式

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《Spring 技术实战4》是一本与Spring框架有关的技术实战书籍。本书内容覆盖了Spring框架的核心技术与应用场景,并且结合了实战案例,通过实际开发过程中遇到的问题及其解决方案,帮助读者更好地理解和掌握Spring框架。 本书具体包括Spring框架的基本概念、IOC(控制反转)和DI(依赖注入)、AOP(面向切面编程)技术、Spring MVC(模型视图控制器)的应用以及Spring Boot(快速构建Spring应用)的实践等方面的内容。此外,还涉及了数据库、事务、集成测试和安全认证等方面的内容。 本书是一本适合中级开发人员阅读的书籍,需要读者具备一定的Java技术基础,并且需要对Spring框架有一定的了解。在阅读本书时,读者可以通过跟随书中的案例代码,逐步深入学习Spring框架的相关技术,从而能够在实际项目中应用到所学的知识。 总之,《Spring 技术实战4》是一本权威的Spring框架实战教程,无论是对于想要深入学习Spring技术的Java开发人员还是对于正在实际开发项目中遇到Spring技术相关问题的开发人员都是一本必读的好书。 ### 回答2: Spring是一款流行的开源框架,它为Java应用程序开发提供了广泛的功能支持,包括依赖注入、面向切面编程、数据访问、集成测试等。在Spring实战4这本书中,作者通过实际示例和案例,深入浅出地介绍了使用Spring开发企业级Java应用程序的实践技巧和经验。 该书分为三个部分,每个部分都涵盖了一个不同的主题。第一部分介绍了Spring的基础知识和核心概念,例如依赖注入、AOP、声明式事务和Spring MVC。第二部分重点讲解了如何使用Spring开发企业级应用程序,包括数据访问、使用Spring集成与消息传递和使用Spring Boot构建可扩展的应用程序。第三部分则介绍了一些高级主题,例如Spring Security、Spring集成测试、Spring Rest和Spring WebFlux。 总的来说,这本书为初学者和有经验的开发人员提供了很多有价值的信息和实践经验,包括如何正确地使用Spring框架、如何构建一些流行的企业应用程序和如何解决开发过程中遇到的一些常见问题。从初学者到专家,每个读者都可以从这本书中找到对自己有用的信息。 ### 回答3: Spring技术实战(第4版)是一本全面介绍Spring框架的实战指南。这本书提供了丰富的例子和各种技术的实现方案,对于刚接触Spring框架的初学者来说尤其有用。本书第一部分重点介绍Spring的基础知识,包括Spring的IOC和AOP原理、Spring MVC框架和Restful服务等。第二部分介绍了Spring的高阶应用,例如Spring与NoSQL数据库的结合、使用Spring实现分布式和云端应用等。本书还涵盖了最新的Spring 5框架,并介绍了一些新增的特性,例如响应式编程和函数式编程。此外,本书还包括了一些对于Java开发者来说非常有用的主题,例如Spring Boot、Spring Security和Spring Data等。总之,Spring技术实战(第4版)是一本非常棒的Spring框架教程和实战指南,可以帮助Java开发者更好地理解和应用Spring框架。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值