Spring-Aop
AOP
AOP简介
- 在软件业,AOP为
Aspect Oriented Programming
的缩写,意为:面向切面编程
。- 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
- AOP是
OOP的延续
,是软件开发中的一个热点
,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。- 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
开发存在的问题
JDK动态代理
JDK动态代理依赖接口
,商品的Dao做一个保存,现在过了一段时间,我想在商品的Dao保存之前做一个权限校验,就相当于对这个功能的增强,哪你就可以使用代理的形式对这个功能进行增强,没有接口是使用不了JDK的动态代理的。
接口当中定义规范
创建实现
测试类
这是你第一次这个功能已经写好了,产品经理来和你说,现在要在保存之前做一个权限的校验,不使用代理,不使用如何的情况下。
只能自己单独的写上一个功能
测试类
这样写修改源代码,不好,我们想要办到不修改原有类的基础上面,对这个功能进行增强。
也就是说在这里不写了,通过代理的形式我能够办到,在保存之前添加一个权限校验。
创建一个类,这个类就是专门生成动态代理,就相当于写一下Aop内部的实现,看他是怎么做的。
在这个类中,先提供一个方法,这个方法让他返回一个对象,返回一个代理对象。
参数:
谁的代理,你要给谁增强,就是谁。
在内部就能直接对代码进行增强。
今后你一想到JDK的动态代理,首先想到 Proxy
参数说明
ClassLoader
: 类加载器 (可以通过字节码获取类加载器)。
Interface
: 接口 。
h
: 处理的调用,方法的回调,今后点击增强对象的所有方法,都会经过这里。
他并没有给你执行,需要你手动的来去执行。
返回一个代理对象,今后你通过返回的这个代理对象调用方法的时候,所有的方法都会经过这里面。
当代理对象他里面的方法执行时,会来到 invoke
里面,如果说调用save的时候他来到了 invoke 这就说明所有的方法已经拦截了。
测试类
所有的方法都会经过这个 回调
指定某些方法,添加额外功能
方法执行之后添加一些功能,也就是不着急返回,在添加完一个功能之后再返回。
cglib动态代理
Aop内部会自动帮你去切换,如果有接口就自动会选择JDK动态代理,没有接口就会自动的选择cglib。
Cglig是一个第三方开源代码 生成类库,动态添加类的属性和方法。
接下来就来看一下cglib内部到底是怎么做的吧,使用cglib就必须的要导入Jar包, cglib是第三方的
。
Spring核心包当中就已经有了cglib
在没有接口的情况下,如何使用cglib做一个增强呢。
创建一个cglib的代理类,采用的是继承方式来产生的代理对象。
测试类
Spring的AOP简介
- AOP思想最早是由AOP联盟组织提出的。
- Spring使用这种思想最好的框架。
- AspectJ
- Spring的AOP有自己的实现方式,但是这种方式非常繁琐。
- AspectJ 是一个AOP的框架。
- Spring放弃了自己传统的方式 ,引入AspectJ作为自身AOP的开发。
AOP相关术语
Joinpoint 连接点
-
可以被拦截到的方法。
-
能够被增强的方法,这些方法就可以称为是连接点。
Pointcut 切入点
- 真正被拦截的方法。
- 真正被增加的方法
Advice 通知
- 增加的内容,通常都是封装成一个方法, 这个方法我们就称为通知。
Introduction 引介
- 类层面的增加。
- 给原有的类添加一些新的属性方法。
- 在开发中通常都是给方法进行增加。
Target 被增加的对象
Weaving 织入
- 将通知应用到目标对象的过程。
Proxy 代理对象
Aspect 切面
- 多个通知和多个切入点的集合。
Spring中AOP使用
- 1.引入Spring基本jar包。
- 2.引入Aop开发的相关jar包。
- 3.配置文件中引入Aop约束。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
- 4.Spring测试。
- 测试时,每次都需要获取工厂。
- 通过spring-test,就不用每次获取。
- 添加测试依赖包
- 5.测试。
- 6.编写一个切面类。
- 7.将切面交给Spring。
- 8.配置AOP完成对目标产生代理。
AOP通知类型
前置通知 aop:before
- 在目标方法执行之前进行操作。
后置通知 aop:after-returning
- 在目标方法执行之后 进行操作。
- 还可以接收方法的返回值
环绕通知 aop:around
- 在目标方法执行之前 和之后进行操作。
异常抛出通知 aop:after-throwing
- 在程序出现异常时进行操作。
- 可以接收到异常的信息。
最终通知 aop:after
- 无论代码是否有异常,都会执行。
- 没有异常的情况下。
AOP切入点表达式
- 基于
execution
函数完成。 - 语法
【访问修饰符】
方法返回值
包名.类名.方法名
(参数)
- public com.qc.demo2.GoodsDaoImpl.save(
..
)参数为任意参数
*
com.qc.demo2.GoodsDaoImpl.save(..)*
任意类型*
com.qc.demo2.GoodsDaoImpl+
.save(..)+
当前类和子类*
com.qc..*.*
(..)com.qc
包以及子包下面所有类的所有方法
AOP注解方式ApsectJ开发
- 1.引入Jar包。
- 2.引入配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
- 3.编写切面类配置。
-
4.使用注解的AOP对象目标类进行增强。
- 在配置文件中开启以注解形式进行AOP开发。
- 在切面类上添加注解。
注解AOP通知类型
@Before
前置通知
@AfterReturning
后置通知- 没有返回值
- 有返回值
@Around
环绕通知
@AfterThrowing
异常抛出通知- 没有获取异常信息
- 获取异常信息
@After
最终通知
AOP的注解切入点的配置
- 有时候一个方法要添加前置通知对又要添加异常通知,又要添加最终通知。
- 可以在切面当中定义好切入点。
- 在通知当中直接使用定义好的切入点表达式。
定义多个切入点
- 一个通知同时定义到多个方法当中。
当使用接口时与不使用接口内部代理区别
- 没使用接口
- 使用接口