[Spring]Spring AOP学习笔记(2)---5种切入方式、AOP优先级及切面表达式的重用

本文主要是介绍[Spring]Spring AOP学习笔记(2)---5种切入方式、AOP优先级及切面表达式的重用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Spring AOP学习笔记(2)---5种切入方式、AOP优先级及切面表达式的重用

一、5种切入方式

学习了下Spring的AOP的五种切入方式,分别是:

(1)Before ---在所拦截方法执行前执行;

(2)After ---在所拦截方法执行后执行;

(3)AfterRuturning  ---在所拦截方法返回值后,执行;

(4)AfterThrowing ---当所拦截方法抛出异常时,执行;

(5)Around ---最为复杂的切入方式,刚方式可以包括上述4个方式。


现在假设切入点为A_Method(假设该方法的执行输出为“A”)。

方式(1)的切入方式的结果为:

             before

             A


方式(2)的切入方式的结果为:

             A

     after


方式(3)的切入方式的结果为:

             A

    afterreturning

方式(4)的切入方式的结果为:

         (有异常,则抛出,执行)


方式(5)的切入方式的结果为:

         可以是上述四种的任意组合。


对于方式(2)(3),是一样的么?其实不然。

区别:拦截方法不管是否有异常,都会执行的是方式(2),即After的切入方式。类似于try-catch-finally,在finally里面的语句。而方式(3)只有当拦截方法成功执行才会执行。

可通过有异常的方法来测试区别(笔者采用的是除0异常)。


二、AOP优先级

如果同时有2个AOP切面,那么如何设定优先级呢?Spring提供了“@order()”的注解方式,@order(1)则表示优先级最高,order(n),n越小,优先级越高。如下例。


图1


图2


图2的加载是优于图1的。 


三、切面表达式的重用

我们发现,添加注解时,我们有相同的内容,这样的东西是否可以重用呢?答案是肯定的。

通过@Pointcut()即可完成切面表达式的重用。如下例。

import java.util.Arrays;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;@Order(3)
@Aspect
@Component
public class testAspect {@Pointcut("execution(* com.spring.aop.test1.*.*(int,int))")public void asp(){}@Before("asp()")public void beforeMethod(JoinPoint joinpoint){Object name = joinpoint.getSignature().getName();Object[] list = joinpoint.getArgs();System.out.println("before.."+name+":"+Arrays.asList(list));}@After("asp()")public void afterMethod(){System.out.println("after..");}@AfterReturning("asp()")public void afterReturningMethod(){System.out.println("afterreturn..");}}


四、AOP的XML配置方式

上一篇记录了AOP的5种切入方式,但是所有的bean都是基于注解的方式来添加进容器的,这一节采用配置文件方式进行配置。贴上代码。如下。

package com.spring.aop.test3;public interface jisuan {public int add(int i,int j);public int mul(int i,int j);public int sub(int i,int j);public int div(int i,int j);
}

package com.spring.aop.test3;public class jisuanimpl implements jisuan {@Overridepublic int add(int i, int j) {// TODO Auto-generated method stub
//		System.out.println("add is begin..");//mul,sub,div都是int result = i+j;System.out.println(result);
//		System.out.println("add is over..");return result;}@Overridepublic int mul(int i, int j) {// TODO Auto-generated method stubint result = i*j;System.out.println(result);return result;}@Overridepublic int sub(int i, int j) {// TODO Auto-generated method stubint result = i-j;System.out.println(result);return result;}@Overridepublic int div(int i, int j) {// TODO Auto-generated method stubint result = i/j;System.out.println(result);return result;}}

package com.spring.aop.test3;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-aop-2.xml");jisuan js = (jisuan) ctx.getBean("js"); js.add(4, 2);}
}

package com.spring.aop.test3;import java.util.Arrays;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;public class testAspect {public void asp() {}public void beforeMethod(JoinPoint joinpoint) {Object name = joinpoint.getSignature().getName();Object[] list = joinpoint.getArgs();System.out.println("before.." + name + ":" + Arrays.asList(list));}public void afterMethod() {System.out.println("after..");}public void afterReturningMethod() {System.out.println("afterreturn..");}public int aroundMethod(ProceedingJoinPoint pjp) {int result = 0;try {System.out.println("before method..");result=(int) pjp.proceed();System.out.println("afterreturning method..");} catch (Exception e) {System.out.println("throwable exception..");// TODO Auto-generated catch blocke.printStackTrace();} catch (Throwable e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("after method..");return result;}}


<?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.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"><bean id="js" class="com.spring.aop.test3.jisuanimpl"></bean><bean id="testAspect" class="com.spring.aop.test3.testAspect"></bean><!-- 配置AOP --><aop:config><!-- 配置切面表达式 --><aop:pointcut expression="execution(* com.spring.aop.test3.*.*(int,int))"id="point" /><aop:aspect ref="testAspect" order="1"><!-- 	<aop:before method="beforeMethod" pointcut-ref="point" /><aop:after method="afterMethod" pointcut-ref="point"/> --><!-- 环绕通知 --><aop:around method="aroundMethod" pointcut-ref="point"/></aop:aspect></aop:config>
</beans>


下面的为运行结果。



在编写@around的method遇到错误: Exception in thread "main"org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: ........

原因是,@around()方法指定的方法的返回值类型必须是和拦截方法的返回值数据类型一致。本例的add()、mul()等方法的返回类型为int,那么@around()指定的方法的返回类型必须是int,不然会报上面的错。

---------------------分割线----------------------------


2016年6月21日,在华为实习期间,使用Spring AOP解决了记录日志的功能。

特此记录一些心得:

(1)这篇我所写的博文,时隔一年再来看,内容较为粗糙

(2)AOP的配置,可以仅仅通过XML进行配置,也可以通过注解的方式进行配置。

(3)配置如@Around等切入方式的方法,其返回类型应与切入点保持一致,这一点在其他很多博文中都没有看到有所体现。这里需要注意下。

这篇关于[Spring]Spring AOP学习笔记(2)---5种切入方式、AOP优先级及切面表达式的重用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/196364

相关文章

springboot健康检查监控全过程

《springboot健康检查监控全过程》文章介绍了SpringBoot如何使用Actuator和Micrometer进行健康检查和监控,通过配置和自定义健康指示器,开发者可以实时监控应用组件的状态,... 目录1. 引言重要性2. 配置Spring Boot ActuatorSpring Boot Act

使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)

《使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)》在现代软件开发中,处理JSON数据是一项非常常见的任务,无论是从API接口获取数据,还是将数据存储为JSON格式,解析... 目录1. 背景介绍1.1 jsON简介1.2 实际案例2. 准备工作2.1 环境搭建2.1.1 添加

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

java如何分布式锁实现和选型

《java如何分布式锁实现和选型》文章介绍了分布式锁的重要性以及在分布式系统中常见的问题和需求,它详细阐述了如何使用分布式锁来确保数据的一致性和系统的高可用性,文章还提供了基于数据库、Redis和Zo... 目录引言:分布式锁的重要性与分布式系统中的常见问题和需求分布式锁的重要性分布式系统中常见的问题和需求

SpringBoot基于MyBatis-Plus实现Lambda Query查询的示例代码

《SpringBoot基于MyBatis-Plus实现LambdaQuery查询的示例代码》MyBatis-Plus是MyBatis的增强工具,简化了数据库操作,并提高了开发效率,它提供了多种查询方... 目录引言基础环境配置依赖配置(Maven)application.yml 配置表结构设计demo_st

在Ubuntu上部署SpringBoot应用的操作步骤

《在Ubuntu上部署SpringBoot应用的操作步骤》随着云计算和容器化技术的普及,Linux服务器已成为部署Web应用程序的主流平台之一,Java作为一种跨平台的编程语言,具有广泛的应用场景,本... 目录一、部署准备二、安装 Java 环境1. 安装 JDK2. 验证 Java 安装三、安装 mys

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

Jsoncpp的安装与使用方式

《Jsoncpp的安装与使用方式》JsonCpp是一个用于解析和生成JSON数据的C++库,它支持解析JSON文件或字符串到C++对象,以及将C++对象序列化回JSON格式,安装JsonCpp可以通过... 目录安装jsoncppJsoncpp的使用Value类构造函数检测保存的数据类型提取数据对json数

Redis事务与数据持久化方式

《Redis事务与数据持久化方式》该文档主要介绍了Redis事务和持久化机制,事务通过将多个命令打包执行,而持久化则通过快照(RDB)和追加式文件(AOF)两种方式将内存数据保存到磁盘,以防止数据丢失... 目录一、Redis 事务1.1 事务本质1.2 数据库事务与redis事务1.2.1 数据库事务1.