Spring全家桶之Spring核心篇,深度分析IoC以及AOP

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: Spring 框架不局限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何 Java 应用都可以从 Spring 中受益。Spring 框架还是一个超级粘合平台,除了自己提供功能外,还提供粘合其他技术和框架的能力。

第一章 IoC控制反转


1.1 控制反转的概念


  • 控制反转(IoC,Inversion of Control),是一个概念,是一种思想。指将传统上由程序代 码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理。控制反转就是对对 象控制权的转移,从程序代码本身反转到了外部容器。通过容器实现对象的创建,属性赋值, 依赖的管理。
  • 控制: 创建对象,对象的属性值赋值,对象之间的关系管理。
  • 反转: 把原来的开发人员管理,创建对象的权限转移交给代码之外的容器实现。由容器代替开发人员管理对象。创建对象,给属性赋值。
  • 正转: 把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现。由容器代替开发人员管理对象,创建对象,给属性赋值。
  • 容器: 是一个服务软件,一个框架(Spring)
  • Ioc 的实现
  • 依赖查找:DL( Dependency Lookup ),容器提供回调接口和上下文环境给组件。
  • 依赖注入:DI(Dependency Injection),程序代码不做定位查询,这些工作由容器自行完成。Spring 框架使用依赖注入(DI)实现 IoC。

Java中创建对象的方式

  • 构造方法,new Student()
  • 反射 :Class
  • 序列化 :数据库
  • 克隆 : Clone
  • 动态代理 :AOP
  • IoC : 控制反转

IoC的体现

之前学习到的应用控制反转的实例:Servlet对象的创建管理,这一工作完全交给了Web容器。

Tomcat就是一个容器:里面存放有Servlet对象、Listener对象、Filter对象等。

IoC的技术实现

  • DI是IoC的技术实现,DI(Dependency Injection) : 依赖注入,只需要在程序中提供要使用的对象名就可以,至于对象如何在容器中创建、赋值、查找都由容器内部实现。
  • Spring是使用DI实现了IoC的功能,Spring底层创建对象,是使用的反射机制


第三章 AOP 面向切面编程


3.1 动态代理


动态代理的分类

  • jdk动态代理:使用jdk中的Proxy、Method、InvocationHanderl创建代理对象。jdk动态代理要求目标类必须实现接口。要求:目标类中必须实现接口
  • cglib动态代理:第三方工具,创建代理对象,原理是继承。通过继承目标类,创建子类,子类就是代理对象。要求:目标类必须能够继承,目标类不能是final的,方法也不能是final的。其子类就是代理对象。

动态代理的作用:

  • 在目标类源代码不改变的情况下,增加新的功能(即方法)
  • 减少代码的重复
  • 专注业务逻辑代码
  • 解耦合,让你的业务红能和日志,事务与非事务功能分离


3.2 AOP面向切面编程


  • AOP就是基于动态代理的,可以使用jdk、cglib两种代理模式。AOP就是动态代理的规范化,把动态代理的实现步骤,方式都定义好了,让开发人员用一种统一的方式,使用动态代理。它的功能和动态代理是一样的。

AOP(Aspect Orient Programming),面向切面编程。面向切面编程是从动态角度考虑程序运行过程。

AOP 底层,就是采用动态代理模式实现的。采用了两种代理:JDK 的动态代理,与 CGLIB 的动态代理。

所谓的切面:就是给目标类增加的额外的功能。

切面的特点:一般都是与业务无关的功能,并且这个功能可以独立使用。

精准概念:

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

怎么理解面向切面编程

  • 需要在分析项目功能时,找出切面(重点)
  • 合理的安排切面的执行时间(在目标放前,还是目标方法之后。)
  • 合理的安排切面执行的位置,在哪个类,哪个方法中增加切面。

针对AOP切面编程的分析

  • 面向切面编程,就是将交叉业务逻辑封装成切面,利用 AOP 容器的功能将切面织入到 主业务逻辑中。所谓交叉业务逻辑是指,通用的、与主业务逻辑无关的代码,如安全检查、 事务、日志、缓存等。 若不使用 AOP,则会出现代码纠缠,即交叉业务逻辑与主业务逻辑混合在一起。这样, 会使主业务逻辑变的混杂不清。
  • 例如,转账,在真正转账业务逻辑前后,需要权限控制、日志记录、加载事务、结束事 务等交叉业务逻辑,而这些业务逻辑与主业务逻辑间并无直接关系。但,它们的代码量所占 比重能达到总代码量的一半甚至还多。它们的存在,不仅产生了大量的“冗余”代码,还大 大干扰了主业务逻辑---转账。

面向切面编程有什么好处

  • 减少重复代码的书写
  • 专业业务的开发

注意:面向切面编程只是面向对象的一种补充。

使用AOP减少重复代码,专注业务实现

微信截图_20220610100728.png

3.3 AOP编程术语(重点)


3.3.1 切面(Aspect)


  • 切面泛指交叉业务逻辑。上例中的事务处理、日志处理就可以理解为切面。常用的切面 是通知(Advice)。实际就是对主业务逻辑的一种增强。切面就是表示功能的增强,就是一堆实现某个功能的代码,并且这个功能与业务没有关系。可以独立运行,时独立于业务存在的一段功能代码。常见的切面:日志、事务、统计信息、参数检查、权限验证等。


3.3.2 连接点(JoinPoint)


  • 连接点指可以被切面织入的具体方法,通常业务接口中的方法均为连接点。连接业务方法和切面的位置,就是某个业务接口中的业务方法。


3.3.3 切入点(Pointcut)


  • 切入点指声明的一个或多个连接点的集合。通过切入点指定一组方法。

注意:被标记为 final 的方法是不能作为连接点与切入点的。因为最终的是不能被修改的,不 能被增强的。


3.3.4 目标对象(Target)


  • 目 标 对 象 指 将 要 被 增 强 的 对 象 。 即 包 含 主 业 务 逻 辑 的 类 的 对 象 。 上 例 中 的 StudentServiceImpl 的对象若被增强,则该类称为目标类,该类对象称为目标对象。当然, 不被增强,也就无所谓目标不目标了。


3.3.5 通知(Advice)


  • 通知表示切面的执行时间,Advice 也叫增强。上例中的 MyInvocationHandler 就可以理 解为是一种通知。换个角度来说,通知定义了增强代码切入到目标代码的时间点,是目标方 法执行之前执行,还是之后执行等。通知类型不同,切入时间不同。

切入点定义切入的位置,通知定义切入的时间。


3.4 AOP实现框架


3.4.1 一个切面的三个关键要素


  • 切面的功能代码:代表切面干什么了
  • 切面的执行位置 ,使用Pointcut表示切面执行的位置
  • 切面的执行时间,使用Advice表示时间,在目标放之前,还是在目标方法之后。


3.4.2 AOP技术的实现


AOP是一个规范,是动态代理的一个规范化,一个标准。

AOP的技术实现框架的技术(两种)

  • spring : spring在内部实现了aop规范,可以完成aop的工作。spring主要在事务处理的时候使用aop。在实际开发中,很少使用spring的aop实现。因为spring的aop比较笨重。
  • aspectJ : 一个开源的专门用来做aop的框架。spring框架中继承了aspectJ 框架,通过spring就可以使用aspectJ框架的功能。


3.5 AspectJ 框架


3.5.1 AspectJ介绍


  • 对于 AOP 这种编程思想,很多框架都进行了实现。Spring 就是其中之一,可以完成面向 切面编程。然而,AspectJ 也实现了 AOP 的功能,且其实现方式更为简捷,使用更为方便, 而且还支持注解式开发。所以,Spring 又将 AspectJ 的对于 AOP 的实现也引入到了自己的框 架中。

在 Spring 中使用 AOP 开发时,一般使用 AspectJ 的实现方式。

  • AspectJ 是一个优秀面向切面的框架,它扩展了 Java 语言,提供了强大的切面实现。AspectJ 是Eclipse基金会的一个开源项目

微信截图_20220610100821.png

  • a seamless aspect-oriented extension to the Javatm programming language(一种基于 Java 平台 的面向切面编程的语言)
  • Java platform compatible(兼容 Java 平台,可以无缝扩展)
  • easy to learn and use(易学易用)


3.5.2 AspectJ实现aop的两种方式


  • 使用xml的配置文件:配置全局事务
  • 使用注解,实际开发中用到的就是注解的方式。aspectJ有5个注解。


3.5.3 AspectJ框架的使用方式


  • 切面的执行时间:这个执行时间在规范中叫做Advice(通知、增强)。在aspectJ框架中使用注解表示。也可以使用xml配置文件中的标签表示。
  • @Before (前置通知)
  • @AfterReturning (后置通知)
  • @Around (环绕通知)
  • @AfterThrowing (异常通知)
  • @After (最终通知)
  • 以上的五个注解都是表示切面执行的时间。
  • 切面的执行位置: 使用切入点表达式


3.5.4 AspectJ的通知类型(了解)


AspectJ中常用的五种类型:

  • 前置通知 (@Before)
  • 后置通知 (@AfterReturning)
  • 环绕通知 (@Around)
  • 异常通知 (@AfterThrowing)
  • 最终通知 (@After)


3.5.5 切入点表达式语法(指定切入点的位置)


AspectJ 定义了专门的表达式用于指定切入点。表达式的原型是:

// 参数之间使用空格分开
execution(modifiers-pattern? ret-type-pattern 
declaring-type-pattern?name-pattern(param-pattern)
throws-pattern?)
// 以上的4个部分,注意这个参数只写参数的类型吗,而不写参数的形参值。
execution(访问权限 方法返回值 包名.类名.方法名称(方法的参数类型) 异常类型)
复制代码

解释AspectJ参数信息

  • modifiers-pattern :访问权限类型
  • ret-type-pattern : 返回值类型
  • declaring-type-pattern :包名类名
  • name-pattern(param-pattern) : 方法名(参数类型和参数个数)
  • throws-pattern : 抛出异常类型

注意:? 代表可选的部分。也就是上面没有标粗的参数。

切入点表达式要匹配的对象就是目标方法的方法名。所以,execution 表达式中明显就 是方法的签名。


3.5.6 切入点表达式使用同配符

微信截图_20220610100859.png

在AspectJ可以使用通配符的目的 :为了可以在配置文件中使用一个注解来获取到多个目标对象,然后给这些目标对象添加统一的功能或者补充其他的功能。

举列说明:(只有返回值类型以及方法名(参数)这两个参数不可以省略,所在在简化的切点表达中肯定存在这两个参数的信息)

  • *execution(public * (..)) : 指定切入点的位置,任意公共的方法。
  • execution( set(...)) :** 指定切入点的位置,任意一个以 "set" 开始的方法。
  • execution( com.yunbocheng.service. .*(..)) :** 指定切入点的位置是service包中的任意类中的任意方法。
  • execution( com.yunbocheng.service.. .(..)):** 指定切入点的位置是 service包或者子包中的任意类的任意方法。".."出现在类名中时,后面必须跟"",表示包、子包下的所有类。
  • execution(..service. * .(..)):* 指定切入点的位置是:多级包下的service子包下所有类(接口)中所有方法为切入点。
  • execution(.service. * .(..)):* 指定切入点的位置是:一级包下的service子包下所有类(接口)中所有方法为切入点。
  • execution( joke(String,)) :** 指定所有的包中的 joke() 方法,该方法的第一个参数为String,第二个参数可以是任意类型。如:joke(String s1,String s2) 、joke(String s1,double d)
  • execution( joke(String,..)):* 所有的 joke()方法,该方法第一个参数为 String,后面可以有任意个参数且 参数类型不限,如 joke(String s1)、joke(String s1,String s2)和 joke(String s1,double d2,String s3) 都是。



相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
1月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
140 26
|
2月前
|
XML Java 开发者
Spring Boot中的AOP实现
Spring AOP(面向切面编程)允许开发者在不修改原有业务逻辑的情况下增强功能,基于代理模式拦截和增强方法调用。Spring Boot通过集成Spring AOP和AspectJ简化了AOP的使用,只需添加依赖并定义切面类。关键概念包括切面、通知和切点。切面类使用`@Aspect`和`@Component`注解标注,通知定义切面行为,切点定义应用位置。Spring Boot自动检测并创建代理对象,支持JDK动态代理和CGLIB代理。通过源码分析可深入了解其实现细节,优化应用功能。
143 6
|
3月前
|
XML Java 数据格式
【SpringFramework】Spring IoC-基于XML的实现
本文主要讲解SpringFramework中IoC和DI相关概念,及基于XML的实现方式。
124 69
|
1月前
|
XML Java 测试技术
Spring AOP—通知类型 和 切入点表达式 万字详解(通俗易懂)
Spring 第五节 AOP——切入点表达式 万字详解!
120 25
|
1月前
|
XML 安全 Java
Spring AOP—深入动态代理 万字详解(通俗易懂)
Spring 第四节 AOP——动态代理 万字详解!
91 24
|
3月前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
71 21
|
3月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
2月前
|
存储 安全 Java
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
104 8
|
3月前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
3月前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
80 14