Spring03

第1章AOP相关概念[理解]

1.1AOP 概述

AOP:全称是 Aspect Oriented Programming 即:面向切面编程。

简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强。

1.1.2 AOP 的作用及优势

作用:在程序运行期间,不修改源码对已有方法进行增强。

优势:

减少重复代码

提高开发效率

维护方便

1.1.3 AOP 的实现方式

使用动态代理技术

1.2AOP 的具体应用

1.2.1 案例中问题

回顾增删查改的例子(参考Spring02)

业务层实现类:

问题就是:事务被自动控制了。换言之,我们使用了 connection 对象的 setAutoCommit(true)此方式控制事务,如果我们每次都执行一条 sql 语句,没有问题,但是如果业务方法一次要执行多条 sql语句,这种方式就无法实现功能了。

我们在业务层中多加入一个方法。

1.2.2 问题的解决

让业务层来控制事务的提交和回滚。

改造后的业务层实现类:没有使用 spring 的 IoC,在方法执行的前后加上事务控制

TransactionManager 类的代码:

最后修配置文件,注意数据源,事务控制的时候queryrunner不能注入数据源了,要重新取链接。

最后结果起到了控制事务的作用

1.2.3 新的问题

通过对业务层改造,已经可以实现事务控制了,但是由于我们添加了事务控制,也产生了一

个新的问题:业务层方法变得臃肿了,里面充斥着很多重复代码。并且业务层方法和事务控制方法耦合了。

试想一下,如果我们此时提交,回滚,释放资源中任何一个方法名变更,都需要修改业务层的代码,况且这还只是一个业务层实现类,而实际的项目中这种业务层实现类可能有十几个甚至几十个。

所以要使用动态代理技术

1.2.4 动态代理

1.2.4.1 动态代理的特点

字节码随用随创建,随用随加载。

它与静态代理的区别也在于此。因为静态代理是字节码一上来就创建好,并完成加载。

装饰者模式就是静态代理的一种体现。

1.2.4.2 动态代理常用的有两种方式

基于接口的动态代理

提供者:JDK 官方的 Proxy 类。

要求:被代理类最少实现一个接口。

基于子类的动态代理

提供者:第三方的 CGLib,如果报 asmxxxx 异常,需要导入 asm.jar。

要求:被代理类不能用 final 修饰的类(最终类)。

1.2.4.3 使用 JDK 官方的 Proxy 类创建代理对象

举例:

在很久以前,演员和剧组都是直接见面联系的。没有中间人环节。

而随着时间的推移,产生了一个新兴职业:经纪人(中间人),这个时候剧组再想找演员就需要通过经纪人来找了。下面我们就用代码演示出来。

一个经纪公司的要求:

* 能做基本的表演和危险的表演

开始使用,一个公司找演员:

通过代理:

间接获取对象,要求:被代理类最少实现一个接口

创建的方式:Proxy.newProxyInstance(三个参数)

参数含义:

ClassLoader:和被代理对象使用相同的类加载器。

Interfaces:和被代理对象具有相同的行为。实现相同的接口。

InvocationHandler:如何代理。

策略模式:使用场景是:

* 数据有了,目的明确。

* 如何达成目标,就是策略。

/**

* 执行被代理对象的任何方法,都会经过该方法。

* 此方法有拦截的功能。

* 参数:

* proxy:代理对象的引用。不一定每次都用得到

* method:当前执行的方法对象

* args:执行方法所需的参数

* 返回值:

* 当前执行方法的返回值

第2章 Spring 中的 AOP

2.1Spring 中 AOP 的细节

2.1.1 说明

spring 的 aop,就是通过配置的方式,实现上一章节的功能。

2.1.2 AOP 相关术语

Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只支持方法类型的连接点。

Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。

Advice(通知/增强):

所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。

通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。

Introduction(引介):

引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方法或 Field。

Target(目标对象):代理的目标对象。

Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。

spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入。

Proxy(代理)一个类被 AOP 织入增强后,就产生一个结果代理类。

Aspect(切面):是切入点和通知(引介)的结合。

2.1.3 学习 spring 中的 AOP 要明确的事

a、开发阶段(我们做的)

编写核心业务代码(开发主线):大部分程序员来做,要求熟悉业务需求。

把公用代码抽取出来,制作成通知。(开发阶段最后再做):AOP 编程人员来做。

在配置文件中,声明切入点与通知间的关系,即切面。:AOP 编程人员来做。

b、运行阶段(Spring 框架完成的)

Spring 框架监控切入点方法的执行。一旦监控到切入点方法被运行,使用代理机制,动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码逻辑运行。

2.1.4 关于代理的选择

在 spring 中,框架会根据目标类是否实现了接口来决定采用哪种动态代理的方式。

2.2基于 XML 的 AOP 配置

示例:

我们在学习 spring 的 aop 时,采用账户转账作为示例。

并且把 spring 的 ioc 也一起应用进来。

2.2.1 环境搭建

2.2.1.1 第一步:准备必要的代码

此处包含了实体类,业务层和持久层代码。我们沿用上一章节中的代码即可。

2.2.1.2 第二步:拷贝必备的 jar 包到工程的 lib 目录

2.2.1.3 第三步:创建 spring 的配置文件并导入约束

2.2.1.4 第四步:配置 spring 的 ioc

2.2.1.5 第五步:抽取公共代码制作成通知

conectionUtils类

2.2.2 配置步骤

2.2.2.1 第一步:把通知类用 bean 标签配置起来

2.2.2.2 第二步:使用 aop:config 声明 aop 配置

2.2.2.3 第三步:使用 aop:aspect 配置切面

2.2.2.4 第四步:使用 aop:pointcut 配置切入点表达式

2.2.2.5 第五步:使用 aop:xxx 配置对应的通知类型

完整配置:

2.2.3 切入点表达式说明

execution:匹配方法的执行(常用)

execution(表达式)

表达式语法:execution([修饰符] 返回值类型 包名.类名.方法名(参数))

写法说明:

全匹配方式:

public void

com.itheima.service.impl.AccountServiceImpl.saveAccount(com.itheima.domain.Account)

访问修饰符可以省略

void

com.itheima.service.impl.AccountServiceImpl.saveAccount(com.itheima.domain.Account)

返回值可以使用*号,表示任意返回值

*

com.itheima.service.impl.AccountServiceImpl.saveAccount(com.itheima.domain.Account)

包名可以使用*号,表示任意包,但是有几级包,需要写几个*

* *.*.*.*.AccountServiceImpl.saveAccount(com.itheima.domain.Account)

使用..来表示当前包,及其子包

* com..AccountServiceImpl.saveAccount(com.itheima.domain.Account)

类名可以使用*号,表示任意类

* com..*.saveAccount(com.itheima.domain.Account)

方法名可以使用*号,表示任意方法

* com..*.*( com.itheima.domain.Account)

参数列表可以使用*,表示参数可以是任意数据类型,但是必须有参数

* com..*.*(*)

参数列表可以使用..表示有无参数均可,有参数可以是任意类型

* com..*.*(..)

全通配方式:

* *..*.*(..)

注:

通常情况下,我们都是对业务层的方法进行增强,所以切入点表达式都是切到业务层实现类。

execution(* com.itheima.service.impl.*.*(..))

2.2.4 环绕通知

配置方式

你可能感兴趣的:(Spring03)