SSM框架整合及核心要点--SpringIOC/AOP底层原理

一.SpringIOC/AOP底层原理

IoC(最大好处:解耦)

“控制反转(IoC)”也称为“依赖注入(DI)”,是一个定义对象依赖的过程,对象只 和构造参数,工厂方法参数,对象实例属性或工厂方法返回相关。容器在创建这些 bean 的 时候注入这些依赖。这个过程是一个反向的过程,所以命名为依赖反转,对象实例的创建由 其提供的构造方法或服务定位机制来实现。

多容器/父子容器概念

Spring 框架允许在一个应用中创建多个上下文容器。但是建议容器之间有父子关系。可 以通过 ConfigurableApplicationContext 接口中定义的 setParent 方法设置父容器。一旦设置父 子关系,则可以通过子容器获取父容器中除 PropertyPlaceHolder 以外的所有资源,父容器不 能获取子容器中的任意资源(类似 Java 中的类型继承)。典型的父子容器: spring 和 springmvc 同时使用的时候。ContextLoaderListener 创建的 容器是父容器,DispatcherServlet 创建的容器是子容器。

p 域/c 域

Spring2.0 之后引入了 p(property 标签)域、Spring3.1 之后引入了 c(constractor-arg 标签) 域。可以简化配置文件中对 property 和 constructor-arg 的配置。
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第1张图片
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第2张图片

lookup-method

lookup-method 一旦应用,Spring 框架会自动使用 CGLIB 技术为指定类型创建一个动态 子类型,并自动实现抽象方法。可以动态的实现依赖注入的数据准备。
在效率上,比直接自定义子类型慢。相对来说更加通用。可以只提供 lookup-method 方 法的返回值对象即可实现动态的对象返回。在工厂方法难以定制的时候使用。如:工厂方法返回对象类型为接口类型。且不同版本应用返回的对象未必相同时使用。 可以避免多次开发工厂类。
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第3张图片
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第4张图片
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第5张图片

AOP

面向切面编程,其底层原理就是动态代理实现。如果切面策略目标有接口实现,使用 JDK 的动态代理技术;无接口实现则使用 CGLIB 技术生成动态代理。
在商业环境中,接口使用度是非常高的,在这主要分析 Spring 如何使用 JDK 的动态代 理 技 术 生 成 动 态 代 理 对 象 。 主 要 代 码 在 JdkDynamicAopProxy 、 AdvisedSupport 、 DefaultAdvisorChainFactory、ReflectiveMethodInvocation 类中。

JdkDynamicAopProxy.invoke();
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第6张图片
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第7张图片
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第8张图片
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第9张图片
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第10张图片
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第11张图片

AdvisedSupport:getInterceptorsAndDynamicInterceptionAdvice
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第12张图片

DefaultAdvisorChainFactory:getInterceptorsAndDynamicInterceptionAdvice
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第13张图片
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第14张图片
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第15张图片

ReflectiveMethodInvocation. proceed
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第16张图片
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第17张图片

AOP 源码流程图
SSM框架整合及核心要点--SpringIOC/AOP底层原理_第18张图片

AOP 中常用的 Pointcut-expression

AOP 开发中,有非常重要的几个概念,其中有一个概念叫“切点”。代表通知切入到代 码执行流程的那个位置点。切点一般通过表达式定义。spring 框架会通过 SpringEL 来解析表达式。表达式有多种 定义方式。分别对应不同的解析结果。

execution 表达式
语法格式: execution(返回类型 包名.类名.方法名(参数表))
如:execution(java.lang.String com.xxx.service.AService.test(java.lang.Integer))
在类型 com.xxx.service.AService 中有方法 test,且参数为 Integer,返回类型为 String 时 增加切面。 execution(* com.xxx.AService.*(…)) com.xxx.AService 类型中的任意方法,任意类型返回结果,参数表不限定,都增加切面。
应用:最常用。也是相对最通用。根据方法执行的标准,定义切点。如:事务处理,日 志处理。

target 表达式
以目标对象作为切点的表达式定义方式。
语法: target(包名.接口名)
如: target(com.xxx.IA) - 所有实现了 IA 接口的实现类,作为代理的目标对象,会自动 增加通知的织入,实现切面。
应用:为某一个具体的接口实现提供的配置。如:登录。登录的时候需要执行的附属逻 辑是比较多的。在不同的业务流程中,附属逻辑也不同。如:电商中,可能在登录的时候, 需要去执行购物车合并。

this 表达式
实现了某接口的代理对象,会作为切点。 和 target 很类似。
语法: this(包名.接口名) 如: this(com.xxx.IA) - 代理对象 Proxy 如果实现了 IA 接口,则作为连接点。
应用:针对某个具体的代理提供的配置。比 target 切点粒度细致。因为目标对象可以多 实现。代理对象可以针对目标对象实现的多个接口的某一个接口,提供特定的切点。
如:银 行中的登录,银行中的帐户种类非常多。且有交叉。如:借记卡,贷记卡,借记还贷卡,贷 记还贷卡等。可以针对还贷接口提供一个切点,做还贷信息的记录等。

within 表达式
以包作为目标,定义切点。
语法: within(包名.*) - 代表在包中的任意接口或类型都作为切点。
应用: 针对某一个包提供的切点,粒度比 target 粗糙。如:某包中的所有接口都需要 执行某附属逻辑。如:电商平台中的下订单。下订单服务中可能需要特定的逻辑(时间戳校 验,库存检查等),这些逻辑,是其他业务线中不需要提供切面的。

args 表达式
以参数标准作为目标,定义切点。
语法: args(类型,类型) - 代表方法的参数表符合要求的时候,作为切点。参数表是有 顺序的。
应用:主要应用在参数校验中。如:登录的时候必须传递两个字符串参数(登录名和密 码)。可以使用 args 来限定。 配合这 execution 实现。 如: execution( * xxxx.*.login(…) ) args(string,string)。 是使用频率最低的表达式。

你可能感兴趣的:(java框架,spring,java,aop)