spring AOP 编程--AspectJ注解方式 (4)
1. AOP 简介
AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补充.
AOP 的主要编程对象是切面(aspect), 而切面模块化横切关注点.
在应用 AOP 编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里, 以什么方式应用, 并且不必修改受影响的类. 这样一来横切关注点就被模块化到特殊的对象(切面)里.
AOP 的好处:
---每个事物逻辑位于一个位置, 代码不分散, 便于维护和升级
---业务模块更简洁, 只包含核心业务代码.
2. AOP的术语和图形表达
切面(Aspect): 横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象
通知(Advice): 切面必须要完成的工作
目标(Target): 被通知的对象
代理(Proxy): 向目标对象应用通知之后创建的对象
连接点(Joinpoint):程序执行的某个特定位置:如类某个方法调用前、调用后、方法抛出异常后等。连接点由两个信息确定:方法表示的程序执行点;相对点表示的方位。例如 ArithmethicCalculator#add() 方法执行前的连接点,执行点为 ArithmethicCalculator#add(); 方位为该方法执行前的位置
切点(pointcut):每个类都拥有多个连接点:例如 ArithmethicCalculator 的所有方法实际上都是连接点,即连接点是程序类中客观存在的事务。AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。切点和连接点不是一对一的关系,一个切点匹配多个连接点,切点通过 org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件。
通知:
前置通知(before advice):在切入点之前执行。
后置通知(after returning advice):在切入点执行完成后,执行通知。无论是否抛出异常,都会执行。在后置通知中不能访问方法返回的结果
环绕通知(around advice):包围切入点,调用方法前后完成自定义行为。
异常通知(after throwing advice):在切入点抛出异常后,执行通知。
方式一、aspectj注解:
1、需要引入一个
2、ArithmeticCalculator.java

1 package com.proc;
2
3 public interface ArithmeticCalculator {
4 int add(int i, int j);
5 int sub(int i, int j);
6
7 int mul(int i, int j);
8 int div(int i, int j);
9 }

3、ArithmeticCalculatorImpl.java

1 package com.proc;
2 import org.springframework.stereotype.Component;
3
4
5 @Component("arithmeticCalculator")
6 public class ArithmeticCalculatorImpl implements ArithmeticCalculator{
7 public int add(int i, int j) {
8 int result = i + j;
9 return result;
10 }
11
12 public int sub(int i, int j) {
13 int result = i - j;
14 return result;
15 }
16
17 public int mul(int i, int j) {
18 int result = i * j;
19 return result;
20 }
21
22 public int div(int i, int j) {
23 int result = i / j;
24 return result;
25 }
26 }

4、LoggingAspect.java

1 package com.proc;
2
3 import org.aspectj.lang.JoinPoint;
4 import org.aspectj.lang.annotation.Aspect;
5 import org.aspectj.lang.annotation.Before;
6 import org.springframework.stereotype.Component;
7
8 @Aspect
9 @Component
10 public class LoggingAspect {
11
12 @Before("execution(* *.*(int,int))")
13 public void beforeMethod(JoinPoint point){
14 System.out.println("正在执行方法: "+point.getSignature().getName());
15 }
16 }

这是一个日志切面类,该类首先是一个IoC中的bean,通过@Component将bean交个容器管理,然后@Aspect声明这是一个切面。
@Before是通知时机,表示在调用方法之前通知。 里面字符串格式为execution (访问修饰符 返回类型 包名.类名.方法名(参数类型...))。
beforeMethod是定一个的一个切面执行的方法,方法名可以任意指定。可以不带参数,也可以指定一个JoinPoint连接点的参数。
配置
1 <context:component-scan base-package="com.proc" />
2 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
aop:aspectj-autoproxy:使得@Aspect注解生效
测试代码:

1 ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
2 ArithmeticCalculator calc=(ArithmeticCalculator) ctx.getBean("arithmeticCalculator");
3 System.out.println(calc.add(3, 5));
4 System.out.println(calc.sub(3, 5));
5 System.out.println(calc.mul(6, 2));
6 System.out.println(calc.div(6, 2));

输出结果

正在执行方法add
8
正在执行方法sub
-2
正在执行方法mul
12
正在执行方法div
3

上面方法是用的前置通知。下面我们讲解一下后置通知、返回通知、异常通知和环绕通知
☆后置通知
后置通知无论方法是否抛出异常,都会执行。在后置通知中不能访问返回结果,因为可能会出现异常,就没有返回值
1 @After("execution(* *.*(int,int))")
2 public void afterMethod(JoinPoint point){
3 System.out.println("方法执行结束: "+point.getSignature().getName());
4 }
☆返回通知
当方法有异常时,不会执行返回通知,只有在方法正常执行结束才能够执行返回通知。在结果通知中用参数returning来指定接收返回结果对象的名称,直接传递给下面方法中对应的参数
1 @AfterReturning(value="execution(* *.*(int,int))",returning="retVal")
2 public void afterReturningMethod(JoinPoint point,Object retVal){
3 System.out.println("方法: "+point.getSignature().getName()+"执行结果为:"+retVal);
4 }
☆异常通知
当方法有异常时,才会执行返回异常通知
1 @AfterThrowing(value="execution(* *.*(int,int))",throwing="ex")
2 public void afterThrowingMethod(JoinPoint point,Exception ex){
3 System.out.println("执行方法: "+point.getSignature().getName()+"出现了异常:"+ex.getMessage());
4 }
【注意】:在指定异常类型时,只能捕获到该类型或子类型的异常。比如指定NullPointerException异常,就只能捕获空指针异常,所以,我们可以指定为异常的父类型。
☆环绕通知
环绕通知是一个比较强大,但相对复杂一点的通知,我们通常不使用

1 @Around("execution(* *.*(int,int))")
2 public Object aroundMethod(ProceedingJoinPoint point){
3
4 System.out.println("环绕通知: "+point.getSignature().getName());
5 Object result=null;
6 //这里相当于前置通知
7 try {
8 //执行方法
9 result= point.proceed();
10 //这里相当于结果通知
11 } catch (Throwable e) {
12 //这里相当于异常通知
13 e.printStackTrace();
14
15 }
16 //这里相当于后置通知
17 System.out.println("环绕通知: "+point.getSignature().getName());
18 return result;
19 }

【注意】:环绕通知要求有一个返回值point.proceed()执行方法,并提供一个返回值
spring AOP 编程--AspectJ注解方式 (4)的更多相关文章
- spring AOP编程--AspectJ注解方式
1. AOP 简介 AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, ...
- Spring——AOP(面向切面编程)@AspectJ注解方式
一.什么是AOP? AOP: (Aspect Oriented Programming)即面向切面编程. 试想这样的场景:项目中需要在业务方法执行完打印日志记录.最笨的办法就是在每个方法核心业务执行完 ...
- SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP
AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分 ...
- spring AOP (使用AspectJ的注解方式 的aop实现) (6)
目录 一.在 Spring 中启用 AspectJ 注解支持 二.AspectJ 支持 5 种类型的通知注解: 2.1.使用之前的 计算器接口和实现类 ArithmeticCalculator.jav ...
- Spring AOP编程(二)-AOP实现的三种方式
AOP的实现有三种方式: l aop底层将采用代理机制进行实现. l 接口 + 实现类 :spring采用 jdk 的动态代理Proxy. l 实现类: ...
- 比较分析 Spring AOP 和 AspectJ 之间的差别
面向方面的编程(AOP) 是一种编程范式,旨在通过允许横切关注点的分离,提高模块化.AOP提供方面来将跨越对象关注点模块化.虽然现在可以获得许多AOP框架,但在这里我们要区分的只有两个流行的框架:Sp ...
- spring aop与aspectj
AOP:面向切面编程 简介 AOP解决的问题:将核心业务代码与外围业务(日志记录.权限校验.异常处理.事务控制)代码分离出来,提高模块化,降低代码耦合度,使职责更单一. AOP应用场景: 日志记录.权 ...
- Spring AOP四种实现方式Demo详解与相关知识探究
一.前言 在网络上看到一篇博客Spring实现AOP的4种方式,博主写的很通俗易懂,但排版实在抓狂,对于我这么一个对排版.代码格式有强迫症的人来说,实在是不能忍受~~~~(>_<)~~~~ ...
- Comparing Spring AOP and AspectJ
AOP 概念 在我们开始之前 , 让我们做一个快速.高级别审查的核心术语和概念 : 方面 — —标准 / 特征代码被分散在多个场所中的应用 , 通常不同于实际的业务逻辑 (例如 , 交易管理) .各方 ...
随机推荐
- 判断访问浏览器客户端类型(pc,mac,ipad,iphone,android)
<script type="text/javascript"> //平台.设备和操作系统 var system = { win: false, mac: false, ...
- 暴力三维树状数组求曼哈顿距离求最值——牛客多校第八场D
涉及的知识点挺多,但是大多是套路 1.求曼哈顿距离的最值一般对所有情况进行讨论 2.三维树状数组用来求前缀最大值 /* 有一个三维坐标系(x,y,z),取值范围为[1,n],[1,m],[1,h],有 ...
- 最小表示法——牛客多校第七场A
脑瘫一样暴力,贪心找最小表示的串,判一个串是否是最小表示法时也是暴力地判.. 但是想不通复杂度是怎么算的.. #include<bits/stdc++.h> using namespace ...
- NX二次开发-UFUN获取直线的两个端点UF_CURVE_ask_line_data
NX9+VS2012 #include <uf.h> #include <uf_obj.h> #include <uf_ui.h> UF_initialize(); ...
- NX二次开发-常用lib库文件
在项目属性->配置属性->链接器->输入->附加依赖项: libufun.lib UFUNC API 函数库 libugopenint.lib UFUNC 对话框 API 函数 ...
- LeetCode 181. Employees Earning More Than Their Managers (超过经理收入的员工)
题目标签: 题目给了我们一个 员工表,包括经理.员工会有经理的id. 这里可以重复 利用两次 表格,表格a, 表格b,当a 员工的经理id 等于 b员工时候,在从中找到员工工资大于经理的.具体看co ...
- git相关操作。
之前只会用图形端的GIT中,命令行的比较陌生,整理下,供自己以后参考 关键的名词: 工作区:工作区 Index / Stage:暂存区 仓库:仓库区(或本地仓库) 远程控制:远程仓库 到项目目录下gi ...
- hexo next主题深度优化(二),懒加载。
文章目录 tip:没有耐心的可以直接看:正式在hexo next中加入懒加载(最下面) 废话 背景 懒加载简单介绍 引入js 重点!敲黑板了!!! 完善懒加载函数 懒加载函数可配置的参数 正式在hex ...
- idea 设置默认maven auto import,不需要每次都弹出
1 2 误区 从这里点进去进行设置,或者每次打开项目右击下方的 auto impot都是不对的.
- Springboot-WebSocket获取HttpSession问题
换了新工作,第一个任务就是和这个有关,以前没接触过,没办法,各种度娘.谷哥,大部分都是只言片语,要么就是特定的配置环境还不贴配置--,踩坑无数, 遂整理成笔记 WebSocket协议 WebSocke ...