AOP 简介
AOP概念
AOP作用
AOP优势
OOP开发思路
开发模块执行掉调用顺序
User
Web
Service
DAO
AOP开发思想
抽取 代码中的重复出现代码 即 共性功能部分
AOP概念
AOP(Aspect Oriented Programing)面向切面编程 一种编程范式 知道开发者如何租住程序结构
AOP优势
提高代码的可重用性
业务代码编码更简洁
业务代码维护更高效
业务功能扩展更便捷
AOP相关概念
Joinpoint(连接点) 就是方法
Pointcut(切入点) 就是挖掉共性功能的方法
Advice(通知) 就是共性功能 最终以一个方法的形式呈现
Aspect(切面) 就是共性功能与挖的位置的对应关系
Target(目标对象) 就是挖掉功能的方法对应的类产生的对象 这种对象是无法直接完成最终工作的
Weaving(织入) 就是挖掉功能的回填的动态过程
Proxy(代理) 目标对象无法直接完成工作 需要对其进行功能回填 通过创建原始对象的代理对象实现
Introdunction(引入/引介) 就是对原始对象无生有的添加成员变量或成员方法
AOP开发过程
开发阶段(开发者完成)
-
正常的制作程序
-
将非共性功能开发到对应的目标对象类中 并制作成切入点方法
-
将共性独立功能开发出来 制作成 通知
-
再配置文件中 声明切入点
-
再配置文件中 声明切入代纳与通知间的关系 (含 通知类型) 即切面
运行阶段
-
Spring容器加载配置文件 监控所有的切入点方法的执行
-
当监控切入点方法被执行 使用代理机制 动态创建目标对象的代理对象 根据通知类别
-
再代理对象的对应位置将通知独赢的功能织入 完成完整的代理逻辑并执行
AOP
面向切面 编程 通过预编译方式和运行期动态代理 实现程序功能的统一维护的一种技术 AOP是OOP的延续
是软件开发中的一个热点 也是SPring框架中的一个重要的内容 是函数式编程的一种衍生范型 利用AOP可以对业务逻辑的各个
部分进行个离 从而使得业务逻辑各部分之间的耦合度降低 提供程序的可重用性 同时提高了开发的效率
AOP在Spring中的作用
提供声明式事务
允许用户自定义切面
横切关注点
跨越应用程序多个模块的方法或功能 与我们业务逻辑无关的 但是我们需要关注的部分就是横切关注点
如 日志 安全 缓存 事务
切面 横切关注点 被模块化 的特殊对象 即 是一个类
通知 切面必须完成的工作 即 他是类中的一个方法
目标 被通知对象
代理 向目标对象应用通知之后创建的对象
切入点 切面通知 执行的“地点”的定义
连接点 与切入点匹配的执行点
方式一 使用原生的Spring API接口
配置aop config
<aop:config>
ndash 切入点 expression 表达式 execution 要执行的位置
<aop : pointcut id="pointcut" expression="execution(对应的类路径 .*(..))">
ndash 执行环绕增加
<aop :advisor advice-ref = "类名" pointcut-ref = "pointcut">
<aop :advisor advice-ref="类名" pointuct-ref="pointcut">
</aop:config>
方式二 自定义类
<bean id="diy" class="对应的类路径"/>
<aop :config>
// 自定义切面 ref 要引用的类
<aop aspect ref = "diy">
<aop :before method ="before" pointcut-ref="point" />
<aop :after method="after" pointcut-ref="point">
<aop :aspect>
</aop :config>
使用注解实现AOP
配置文件
开启注解的支持
<aop: aspectj-autoproxy />
@Aspect 标注这个类式一个切面
@Before(“execution”) 对应的切入点
- AOP小节 导入坐标 功能分离 配置关系
AOP配置(XML)
切入点
通知
AspectJ
AspectJ (切面) 用于描述切入点与通知间的关系 是AOP编程的一个概念
AspectJ是基于java语言对Aspect的实现
AOP配置
aop:config
beans标签 设置AOP
格式
<beans>
<aop:config></aop:config>
<aop:config></aop:config>
</beans>
-
说明: 一个beans标签中可以配置多个aop:config标签
aop:aspect
设置具体的AOP通知对应的切入点 ,一个aop:config标签可以配置多个aop:sioect标签 ,ref 通知所在的bean的idaop:pointcut
设置切入点 一个aop:config标签可以配置多个aop:pointcut标签 且该标签可以配,aop:aspect标签内**id** 识别切入点的名称 **expression** 切入点表达式
切入点
切入点描述的是某个方法
切入点表达式时一个快速匹配方法描述的统配格式,类似于正则表达式
切入点表达式的组成
切入点描述的时某个方法
切入点表达式是一个快速匹配方法描述的通配格式 类似于正则表达式
关键字 (访问修饰符 返回值 包名.类名.方法名 (参数) 异常名)
关键字 描述表达式的匹配模式
访问修饰符 方法的访问控制权限修饰符
类明 方法所在的类
异常 方法定义中指定抛出的异常
AOP配置(XML)
AOP通知类型
-
前置通知
原始方法执行前执行 如果通知抛出异常 阻止原始方法执行
数据校验 -
后置通知
原始方法执行后执行 无论原始方法中是否出现异常 都将执行通知
现场清理 -
返回后通知
原始方法正常执行后完毕并返回结果后执行 如果原始方法没有抛出异常 无法执行
返回值相关数据处理 -
抛出异常后通知
原始方法抛出异常后执行 如果原始方法没有抛出异常 无法执行
对原始方法中出现的异常信息进行处理 -
环绕通知
在原始方法执行前后均有对应执行 还可以阻止原始方法的执行
十分强大 可以做任何事情
环绕通知开发方式
环绕通知是在原始方法的前后添加功能 在环绕通知中 存在对原始方法的显式调用
public Object around(ProceedingJoint pip ) throws Throwable{
Object ret = pjp.proceed();
return ret;
}
- 环绕通知方法相关说明
-
方法须设定Object类型的返回值 否则会拦截原始方法的返回 如果原始方法返回值类型为void
通知方法也可以设定返回值类型void 最终返回null
方法都在第一个参数位置设定ProceedingJoinPoint对象 通过该对象调用proceed()方法 实现
对原始方法的调用 如省略该参数 原始方法将无法执行
使用proceed()方法调用原始方法时 因无法预知原始方法运行过程中是否会出现异常 强制抛出
Throwable对象 封装原始方法中可能出现的异常信息
AOP 通知获取数据
参数
返回值
异常
设定通知方法第一个参数为JoinPoint 通过该对象getArgs()方法 获取原始方方法运行的参数数组
public void befotr(JoinPoint JP) throw Throwble{
Object[] args = JP.getArgs();
}
所有的通知均可以获取参数
设定切入点表达式为通知方法传递参数 (锁定通知变量名)
原始方法
public void save(int param1 , int param2 ){
System.out.println("user service running");
}
AOP配置
AOP 配置的args对应的参数名 需要和通知类的一样 通过在AOP中配置arg-name 可以改变参数的转入通知顺序
通知类
public void before (int a, int b){
System.out.println(“a=” +a);
System.out.println(“b=” +b);
}