Spring_2023_11_22_1 AspectJ(面向切面编程框架)

AspectJ(面向切面编程框架)

Aspectj是一个基于java的、面向切面的AOP框架。Spring2.0之后增加了对Aspectj切点表达式的支持。而实际开发中一般都使用Aspectj方式来实现AOP。所以还要导入Aspectj相关jar包。

aspectJ 包含通知类型:

  1. before:前置通知
  2. afterReturning:后置通知(可以获取返回值)
  3. afterThrowing:抛出异常的通知
  4. after最终通知
  5. around:环绕通知

案例驱动形式:xml形式

引入依赖 aspectj 框架

<!--
Spring 基础包括 :
Spring-core/Spring-beans/Spring-app/Spring-expression
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
</dependency>
<!--添加lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
<!--aop框架: aspectj-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>

目标类:UserService/UserServiceImpl

package com.bboy.service.impl;
import com.bboy.service.UserService;
/**
* @类描述:
* @作者:秦帅
* @时间:2023/11/22 0022 10:35:49
*/
public class UserServiceImpl implements UserService {
@Override
public int addUser() {
System.out.println("================>addUser");
return 100;
}
@Override
public void updateUser() {
System.out.println("================>updateUser");
}
@Override
public int deleteUserById(int id) {
System.out.println("================>deleteUserById");
return 200;
}
}

切面类:MyAspectj

切面类(包含了多种通知:前置通知、后置通知、后置的返回通知、异常的通知等)

import org.aspectj.lang.JoinPoint;
JoinPoint包不要导错

package com.bboy.aspect;
import org.aspectj.lang.JoinPoint;
/**
* @类描述:
* 切面类(包含了多种通知:前置通知、后置通知、后置的返回通知、异常的通知等)
* @作者:秦帅
* @时间:2023/11/22 0022 10:38:18
*/
public class MyAspectJ {
/*
前置通知
joinpoint :连接点
此对象可以包含目标类当前执行方法的所有信息,如方法名,方法传入的参数
*/
public void myBefore(JoinPoint joinPoint){
//- : 获取方法名
String method_name = joinPoint.getSignature().getName();
//- : 获取方法的参数
Object[] objs = joinPoint.getArgs();
for (Object obj:objs){
System.out.println("参数====》"+obj);
}
System.out.println(method_name+"========>myBefore");
}
/*
后置通知
*/
public void myAfter(JoinPoint joinPoint){
//- : 获取方法名
String method_name = joinPoint.getSignature().getName();
//- : 获取方法的参数
Object[] objs = joinPoint.getArgs();
for (Object obj:objs){
System.out.println("参数====》"+obj);
}
System.out.println(method_name+"========>myAfter");
}
/*
执行后获取返回的通知 通知
参数中 : Object res 方法的返回值
*/
public void myAfterReturning(JoinPoint joinPoint ,Object res){
//- : 获取方法名
String method_name = joinPoint.getSignature().getName();
//- : 获取方法的参数
Object[] objs = joinPoint.getArgs();
for (Object obj:objs){
System.out.println("参数====》"+obj);
}
System.out.println(method_name+"========>myAfterReturning:"+res);
}
/*
执行后抛出异常的通知
参数中 : Throwable e 抛出的异常
*/
public void myAfterThrowing(JoinPoint joinPoint , Throwable e){
//- : 获取方法名
String method_name = joinPoint.getSignature().getName();
//- : 获取方法的参数
Object[] objs = joinPoint.getArgs();
for (Object obj:objs){
System.out.println("参数====》"+obj);
}
System.out.println(method_name+"========>myAfterThrowing:"+e.getMessage());
}
}

核心配置文件中的注册

1. 引入aop命名空间

image

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>

2. 目标类的注册

<!--1.创建目标类-->
<bean id="userService" class="com.bboy.service.impl.UserServiceImpl"/>

3. 切面类的注册

<!--2.创建切面类-->
<bean id="myLogAspect" class="com.bboy.aspect.MyAspectJ"/>

4. Aop配置

aop编写:配置
1.aop:aspect : 声明切面类,从而获取切面类的通知
2.aop:pointcut : 切入点(目标类对应的方法)
3.aop:before : 前置通知
3.1 method 指代前面切面类中的方法(切面类中哪个方法是前置方法)
3.2 pointcut-ref 切入点的引入
4.aop:after : 后置通知
4.1 method 指代前面切面类中的方法(切面类中哪个方法是后置方法)
4.2 pointcut-ref 切入点的引入
5.aop:after-returning : 执行完毕之后返回值的通知
5.1 method 指代前面切面类中的方法
5.2 pointcut-ref 切入点的引入
5.3 returning : 返回值的参数名
注意: returning的返回值内容,必须和切面类中对应方法的参数名一致
6.aop:after-throwing : 执行完毕后抛出的异常的通知
6.1 method 指代前面切面类中的方法
6.2 pointcut-ref 切入点的引入
6.3 throwing : 异常的信息
注意: throwing的返回值内容,必须和切面类中对性的参数名一致
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1.创建目标类-->
<bean id="userService" class="com.bboy.service.impl.UserServiceImpl"/>
<!--2.创建切面类-->
<bean id="myAspectJ" class="com.bboy.aspect.MyAspectJ"/>
<!--3.aop编写:配置
1.aop:aspect : 声明切面类,从而获取切面类的通知
2.aop:pointcut : 切入点(目标类对应的方法)
3.aop:before : 前置通知
3.1 method 指代前面切面类中的方法(切面类中哪个方法是前置方法)
3.2 pointcut-ref 切入点的引入
4.aop:after : 后置通知
4.1 method 指代前面切面类中的方法(切面类中哪个方法是后置方法)
4.2 pointcut-ref 切入点的引入
5.aop:after-returning : 执行完毕之后返回值的通知
5.1 method 指代前面切面类中的方法
5.2 pointcut-ref 切入点的引入
5.3 returning : 返回值的参数名
注意: returning的返回值内容,必须和切面类中对应方法的参数名一致
6.aop:after-throwing : 执行完毕后抛出的异常的通知
6.1 method 指代前面切面类中的方法
6.2 pointcut-ref 切入点的引入
6.3 throwing : 异常的信息
注意: throwing的返回值内容,必须和切面类中对性的参数名一致
-->
<aop:config proxy-target-class="true">
<aop:aspect ref="myAspectJ">
<!--
2.aop:pointcut : 切入点(目标类对应的方法)
-->
<aop:pointcut id="mypointcut" expression="execution(* com.bboy.service.impl.UserServiceImpl.*(..))"/>
<!--
3.aop:before : 前置通知
3.1 method 指代前面切面类中的方法(切面类中哪个方法是前置方法)
3.2 pointcut-ref 切入点的引入
-->
<aop:before method="myBefore" pointcut-ref="mypointcut"/>
<!--
4.aop:after : 后置通知
4.1 method 指代前面切面类中的方法(切面类中哪个方法是后置方法)
4.2 pointcut-ref 切入点的引入
-->
<aop:after method="myAfter" pointcut-ref="mypointcut"/>
<!--
5.aop:after-returning : 执行完毕之后返回值的通知
5.1 method 指代前面切面类中的方法
5.2 pointcut-ref 切入点的引入
5.3 returning : 返回值的参数名
注意: returning的返回值内容,必须和切面类中对应方法的参数名一致
-->
<aop:after-returning method="myAfterReturning" pointcut-ref="mypointcut" returning="res"/>
<!--
6.aop:after-throwing : 执行完毕后抛出的异常的通知
6.1 method 指代前面切面类中的方法
6.2 pointcut-ref 切入点的引入
6.3 throwing : 异常的信息
注意: throwing的返回值内容,必须和切面类中对性的参数名一致
-->
<aop:after-throwing method="myAfterThrowing" pointcut-ref="mypointcut" throwing="e"/>
</aop:aspect>
</aop:config>
</beans>

测试类

package com.bboy.demo;
import com.bboy.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @类描述:
* @作者:秦帅
* @时间:2023/11/22 0022 11:18:32
*/
public class Demo {
public static void main(String[] args) {
//-:获取 spring 容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//-: 从容器中获取Bean对象
UserService userService = (UserService) context.getBean("userService");
userService.updateUser();
userService.deleteUserById(2);
userService.addUser();
}
}

运行结果

image

posted @   Kbaor  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示