Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement AOP with Spring AspectJ

2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly shows you how Spring AspectJ implements AOP, the content is simple and easy to understand, and the organization is clear. I hope it can help you solve your doubts. Let's take everyone to study and learn about "Spring AspectJ how to implement AOP".

1 What is AspectJ?

AspectJ is an aspect-oriented framework that extends the Java language. AspectJ defines the AOP syntax, or AspectJ is an AOP framework based on the Java language. Usually when we use Spring AOP, we import the relevant jar package of AspectJ.

在 spring2.0以后,spring新增了对AspectJ 切点表达式的支持;Aspect1.5新增注解功能,通过 JDK5的注解技术,能直接在类中定义切面;新版本的 spring 框架,也都建议使用 AspectJ 来实现 AOP。所以说在 spring AOP 的核心包 Spring-aop-3.2.jar 里面也有对 AspectJ 的支持。

2、切入点表达式

上一篇博客中,我们在spring配置文件中配置如下:

那么它表达的意思是 返回值任意,包名为 com.ys.aop 下的任意类名中的任意方法名,参数任意。那么这到底是什么意思呢?

首先 execution 是 AspectJ 框架定义的一个切入点函数,其语法形式如下:

execution(modifiers-pattern? ref-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?) 类修饰符 返回值 方法所在的包 方法名 方法抛出的异常

简单点来说就是:

语法:execution(修饰符 返回值 包.类.方法名(参数) throws异常)

具体解释我们用下面一张思维导图来看:

注意:如果切入点表达式有多个不同目录呢? 可以通过 || 来表示或的关系。

表示匹配 com.ys包下的,以 Service1结尾或者以Service2结尾的类的任意方法。

AOP 切入点表达式支持多种形式的定义规则:1、execution:匹配方法的执行(常用) execution(public *.*(..))2.within:匹配包或子包中的方法(了解) within(com.ys.aop..*)3.this:匹配实现接口的代理对象中的方法(了解) this(com.ys.aop.user.UserDAO)4.target:匹配实现接口的目标对象中的方法(了解) target(com.ys.aop.user.UserDAO)5.args:匹配参数格式符合标准的方法(了解) args(int,int)6.bean(id) 对指定的bean所有的方法(了解) bean('userServiceId')2、Aspect 通知类型

Aspect 通知类型,定义了类型名称以及方法格式。类型如下:

before:前置通知(应用:各种校验) 在方法执行前执行,如果通知抛出异常,阻止方法运行afterReturning:后置通知(应用:常规数据处理) 方法正常返回后执行,如果方法中抛出异常,通知无法执行 必须在方法执行后才执行,所以可以获得方法的返回值。around:环绕通知(应用:十分强大,可以做任何事情) 方法执行前后分别执行,可以阻止方法的执行 必须手动执行目标方法afterThrowing:抛出异常通知(应用:包装异常信息) 方法抛出异常后执行,如果方法没有抛出异常,无法执行after:最终通知(应用:清理现场) 方法执行完毕后执行,无论方法中是否出现异常

这里最重要的是around,环绕通知,它可以代替上面的任意通知。

在程序中表示的意思如下:

try{ //前置:before //手动执行目标方法 //后置:afterRetruning} catch(){ //抛出异常 afterThrowing} finally{ //最终 after}

对应的 jar 包如下:

我们可以查看源码:

3、AOP具体实例①、创建接口package com.ys.aop; public interface UserService { //添加 user public void addUser(); //删除 user public void deleteUser();}②、创建实现类package com.ys.aop; public class UserServiceImpl implements UserService{ @Override public void addUser() { System.out.println("增加 User"); } @Override public void deleteUser() { System.out.println("删除 User"); }}③、创建切面类(包含各种通知) package com.ys.aop; import org.aspectj.lang.JoinPoint; public class MyAspect { /** * JoinPoint 能获取目标方法的一些基本信息 * @param joinPoint */ public void myBefore(JoinPoint joinPoint){ System.out.println("前置通知 : " + joinPoint.getSignature().getName()); } public void myAfterReturning(JoinPoint joinPoint,Object ret){ System.out.println("后置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret); } public void myAfter(){ System.out.println("最终通知"); } }④、创建spring配置文件applicationContext.xml

我们首先测试前置通知、后置通知、最终通知

⑤、测试@Test public void testAop(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService useService = (UserService) context.getBean("userService"); useService.addUser(); }

控制台打印:

注意,后置通知的返回值为 null,是因为我们的目标方法 addUser() 没有返回值。如果有返回值,这里就是addUser() 的返回值。

4、测试异常通知

目标接口保持不变,目标类我们手动引入异常:

public void addUser() { int i = 1/0;//显然这里会抛出除数不能为 0 System.out.println("增加 User"); }

接着配置切面:MyAspect.java

public void myAfterThrowing(JoinPoint joinPoint,Throwable e){ System.out.println("抛出异常通知 : " + e.getMessage()); }public void myAfterThrowing(JoinPoint joinPoint,Throwable e){ System.out.println("抛出异常通知 : " + e.getMessage()); }

接着在 applicationContext.xml 中配置如下:

测试:

@Test public void testAop(){ String str = "com/ys/execption/applicationContext.xml"; ApplicationContext context = new ClassPathXmlApplicationContext(str); UserService useService = (UserService) context.getBean("userService"); useService.addUser(); }

控制台打印:

5. Test surround notification

The target interface and target class remain the same, and MyAspect is modified as follows:

public class MyAspect { public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("pre-notification"); //Manually execute target method Object obj = joinPoint.proceed(); System.out.println("postnotification"); return obj; } }

ApplicationContext.xml is configured as follows:

Testing:

@Test public void testAop(){ String str = "com/ys/around/applicationContext.xml"; ApplicationContext context = new ClassPathXmlApplicationContext(str); UserService useService = (UserService) context.getBean("userService"); useService.addUser(); }

Print Results:

The above is about "Spring AspectJ how to achieve AOP" content, if the article is helpful to you and feel well written, please share with your friends to learn new knowledge, if you want to know more related knowledge content, please pay more attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report