Spring5(七)——AOP注解
一、AOP注解
1、介绍
上一节介绍了 AspectJ 框架如何实现 AOP,具体的实现方式是通过 xml 来进行配置的。xml 方式思路清晰,便于理解,但是书写过于麻烦。这一节介绍注解的方式来进行 AOP 配置。
2、案例(注解)
定义目标对象(被代理的对象)
1 // 定义一个接口
2 public interface ITeacher {
3 void teach();
4 int add(int i, int j);
5 }
6
7 // 定义目标对象
8 @Service
9 public class Teacher implements ITeacher {
10 @Override
11 public void teach() {
12 System.out.println("老师正在上课");
13 }
14
15 @Override
16 public int add(int i, int j) {
17 int add = i + j;
18 System.out.println("执行目标方法:老师正在做加法,结果为:" + add);
19 // int throwable = 10 / 0; 测试异常通知
20 return add;
21 }
22
23 // 目标对象自己的方法,此方法不是接口所以无法代理
24 public void sayHello() {
25 System.out.println("老师会说hello");
26 }
27
28 }
编写一个切面类(通知)
1 // 创建切面类(包含各种通知)
2 @Component
3 @Aspect
4 public class MyAspect {
5
6 // 1.先定义切入点表达式
7 @Pointcut("execution(* com.lx.spring.day4.ITeacher.*(..))")
8 private void myPointcut() {
9
10 }
11
12 // 2.标识此方法为一个前置通知,用来切满足后面切点表达式的方法
13 @Before("myPointcut()")
14 public void myBefore(JoinPoint joinPoint) {
15 System.out.println("前置通知:方法增强myBefore()" + " , -->" + joinPoint.getSignature().getName());
16 }
17
18 @AfterReturning(value = "myPointcut()", returning = "object")
19 public void myAfterReturning(JoinPoint joinPoint, Object object) {
20 System.out.println("后置通知:方法增强myAfterReturning()" + " , -->" + joinPoint.getSignature().getName() + " , -->" + object);
21 }
22
23 public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable {
24 System.out.println("============环绕前==============");
25 Object obj = joinPoint.proceed(); // 手动执行目标方法
26 System.out.println("============环绕后==============");
27 return obj;
28 }
29
30 public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
31 System.out.println("抛出异常通知:" + e.getMessage());
32 }
33
34 public void myAfter() {
35 System.out.println("最终通知:方法增强myAfter()");
36 }
37
38 }
编写配置文件 application.xml
1 <!-- 1.自动扫描(自动注入bean) -->
2 <context:component-scan base-package="com.lx.spring.day4"/>
3
4 <!-- 2.扫描 @Aspect 告诉 spring 这是一个切面类 -->
5 <aop:aspectj-autoproxy/>
1 // 测试类
2 public class Main {
3 public static void main(String[] args) {
4 ApplicationContext app = new ClassPathXmlApplicationContext("app4.xml");
5 ITeacher iTeacher = app.getBean(ITeacher.class);
6
7 iTeacher.add(11, 24);
8 }
9 }
10
11 // 结果
12 前置通知:方法增强myBefore() , -->add
13 执行目标方法:老师正在做加法,结果为:35
14 后置通知:方法增强myAfterReturning() , -->add , -->35
说明:对比 xml 的配置,不难理解注解的方式。
@Service @Component
<context:component-scan base-package="com.lx.spring.day4"/>
用于 Spring 扫描并注册bean。
@Aspect:指明这是一个切面类
<aop:aspectj-autoproxy/>:开启切面注解扫描
3、优先级
有多个增强类对同一个方法进行增强,设置增强类优先级,在增强类上面添加注解 @Order(数字类型值),数字类型值越小优先级越高。
1 @Component
2 @Aspect
3 @Order(1)
4 public class MyAspect2 {}
优先级:这里的优先级,只会影响两个增强类对应的方法,执行的先后顺序。并不会只执行优先级高的。
二、AOP+自定义注解
通过AOP+自定义注解的方式,可以实现前面说的抽取公共非业务模块,对业务逻辑的增强。比如:
需求:①想要对业务逻辑层的所有方法,打印出入参和出参,做日志管理。②对业务逻辑层的方法入口,开启事务,逻辑执行后,提交事务,等。

自定义注解
1 // 用于日志打印
2 @Target({ElementType.METHOD})
3 @Retention(RetentionPolicy.RUNTIME)
4 @Documented
5 public @interface Log {
6
7 String value() default "";
8 }
1 @Component
2 @Aspect
3 public class MyAspect {
4
5 // 定义切入点为 有注解Log的方法
6 @Pointcut("@annotation(com.lx.spring.day5.Log) ")
7 private void myLogPointcut() {
8
9 }
10
11 // 为切入点增强一个环绕通知,可以在这里写打印入参出参的逻辑
12 @Around("myLogPointcut()")
13 public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable {
14 System.out.println("============环绕前==============");
15 Object obj = joinPoint.proceed(); // 手动执行目标方法
16 System.out.println("============环绕后==============");
17 return obj;
18 }
19
20 }
1 @Service
2 public class Teacher implements ITeacher {
3
4 // 为需要打印入参出参的方法 加上@Log注解即可
5 @Log
6 @Override
7 public int add(int i, int j) {
8 int add = i + j;
9 System.out.println("执行目标方法:老师正在做加法,结果为:" + add);
10 // int throwable = 10 / 0; 测试异常通知
11 return add;
12 }
13
14 }
1 public class Main {
2 public static void main(String[] args) {
3 ApplicationContext app = new ClassPathXmlApplicationContext("app4.xml");
4 ITeacher iTeacher = app.getBean(ITeacher.class);
5
6 iTeacher.add(11, 24);
7 }
8 }
9
10 // 结果
11 ============环绕前==============
12 执行目标方法:老师正在做加法,结果为:35
13 ============环绕后==============
Spring5(七)——AOP注解的更多相关文章
- Spring详解(七)------AOP 注解
上一篇博客我们讲解了 AspectJ 框架如何实现 AOP,然后具体的实现方式我们是通过 xml 来进行配置的.xml 方式思路清晰,便于理解,但是书写过于麻烦.这篇博客我们将用 注解 的方式来进行 ...
- 来一手 AOP 注解方式进行日志记录
系统日志对于定位/排查问题的重要性不言而喻,相信许多开发和运维都深有体会. 通过日志追踪代码运行状况,模拟系统执行情况,并迅速定位代码/部署环境问题. 系统日志同样也是数据统计/建模的重要依据,通过分 ...
- Spring详解(六)------AOP 注解
上一篇博客我们讲解了 AspectJ 框架如何实现 AOP,然后具体的实现方式我们是通过 xml 来进行配置的.xml 方式思路清晰,便于理解,但是书写过于麻烦.这篇博客我们将用 注解 的方式来进行 ...
- SpringBoot —— AOP注解式拦截与方法规则拦截
AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件. SpringBoot中AOP的使用 ...
- Spring AOP注解为什么失效?90%Java程序员不知道
使用Spring Aop注解的时候,如@Transactional, @Cacheable等注解一般需要在类方法第一个入口的地方加,不然不会生效. 如下面几种场景 1.Controller直接调用Se ...
- Spring入门(三)— AOP注解、jdbc模板、事务
一.AOP注解开发 导入jar包 aop联盟包. aspectJ实现包 . spring-aop-xxx.jar . spring-aspect-xxx.jar 导入约束 aop约束 托管扩展类和被扩 ...
- SpringBoot整合Mybatis多数据源 (AOP+注解)
SpringBoot整合Mybatis多数据源 (AOP+注解) 1.pom.xml文件(开发用的JDK 10) <?xml version="1.0" encoding=& ...
- Spring AOP注解形式简单实现
实现步骤: 1:导入类扫描的注解解析器 命名空间:xmlns:context="http://www.springframework.org/schema/context" xsi ...
- AOP注解不起作用的debug结果
经过2天的调试,我发现AOP注解配置不起作用居然是表达式的错误导致的 在xml文件中配置的base-package有关,初步认为@PointCut只能使用base-package..*(..)这样的方 ...
随机推荐
- CSS Grid 布局(Grid Layout)完全指南 #flight.Archives003
Title/ CSS Grid 布局(Grid Layout)完全指南 #flight.Archives003 序 : 写完这篇文章后,我准备一直做下去了,包括flight的各个分区,也看到前方的路. ...
- 以命令行方式使用Desktop版Ubuntu
方法1:安装Ubuntu Server版,好处是默认不安装GUI,且可以自动安装ssh服务和其他很多服务,且消耗系统资源少(约200MB内存,Desktop版启动后需要500MB左右内存),启动和关闭 ...
- Create Shortcut to Get Jar File Meta Information
You have to get meta information of cobertura.jar with command "unzip -q -c cobertura.jar META- ...
- 华为应用市场更新APP多次被拒
最近公司的APP发布了新版本,只进行了线上bug的修复,基本没改什么主体业务功能.各大应用市场都顺利更新上架,但是国货之光华为,被闷了几次.拒来拒去,就是那些反复的内容.内容一般如下: 经检测发现,您 ...
- Pikachu-File Inclusion模块
一.概述 文件包含,是一个功能.在各种开发语言中都提供了内置的文件包含函数,其可以使开发人员在一个代码文件中直接包含(引入)另外一个代码文件. 比如 在PHP中,提供了:include(),inclu ...
- 你真的熟悉ASP.NET MVC的整个生命周期吗?
一.介绍 我们做开发的,尤其是做微软技术栈的,有一个方向是跳不过去的,那就是MVC开发.我相信大家,做ASP.NET MVC 开发有的有很长时间,当然,也有刚进入这个行业的.无论如何,如果有人问你,你 ...
- 【Openxml】将Openxml的椭圆弧线arcTo转为Svg的椭圆弧线
本文将介绍如何将OpenXml的actTo转为Svg的弧线(a) OpenXml的artTo 首先下面是一段OpenXml的arcTo弧线 <arcTo wR="152403" ...
- Specification排序orderby
废话不多说直接贴代码 Specification<Course> sf = new Specification<Course>() { @Override public Pre ...
- WPF---数据绑定之Xml数据源(四)
一.场景 现在外部有一xml文件,我们想将该xml文件中的内容绑定到ListView中,该如何实现? 二.实现 xml文件的内容如下: <?xml version="1.0" ...
- redis并发锁
1.应对并发场景 避免操作数据不一致 将对redis加锁 2.考虑到异常状况无法释放锁,导致死锁 将代码块进行try-catch处理 3.考虑try时宕机依然导致死锁 对锁添加时效性,添加过期时间 4 ...