AspectJ(面向切面编程框架)
Aspectj是一个基于java的、面向切面的AOP框架。Spring2.0之后增加了对Aspectj切点表达式的支持。而实际开发中一般都使用Aspectj方式来实现AOP。所以还要导入Aspectj相关jar包。
aspectJ 包含通知类型:
- before:前置通知
- afterReturning:后置通知(可以获取返回值)
- afterThrowing:抛出异常的通知
- after最终通知
- 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命名空间
<?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();
}
}