前言
基于注解开发AspectJ要比基于XML配置开发AspectJ便捷许多,基于XML开发在上一篇已经介绍过|https://blog.csdn.net/qq_43910194/article/details/109015029
AspectJ库的引入在上一篇有。
注解名称 | 描述 |
---|---|
@Aspect | 用于定义一个切面,注解在切面类上 |
@pointcut | 用于定义切入点表达式。在使用时需要定义一个切入点方法,该方法是一个返回值void且方法体为空的普通方法 |
@Before | 用于定义前置通知。使用时为其指定Value属性值,该值为已有的切入点,也可以直接定义切入点表达式 |
@AfterReturning | 用于定义后置返回通知。value值用法同上 |
@Around | 用于定义环绕通知。value值用法同上 |
@AfterThrowing | 定义异常通知。value值用法同上。另外还有一个throwing属性用于访问目标对象抛出的异常。 |
@After | 定义后置(最终)通知。value值用法同上 |
一、XML代码
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="org.example.AspectJNotes"/>
<aop:aspectj-autoproxy/>
</beans>
二、MyAspectJ切面类
package org.example.AspectJNotes;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* 切面类,编写各种通知
*/
@Aspect//切面注解
@Component
public class MyAspectJ {
/**
* 定义切入点
*/
@Pointcut("execution(* org.example.AspectJNotes.*.*(..))")
public void mypointcut(){
//必须定义一个无返回值无方法体的方法,作为切入点
}
/**
* 前置通知,加入切入点
* @param joinPoint 接受对象的参数
*/
@Before("mypointcut()")
public void before(JoinPoint joinPoint){
System.out.println("前置通知处理");
System.out.println("目标类对象:"+joinPoint.getTarget());
System.out.println("增强处理的方法"+joinPoint.getSignature().toString());
}
/**
* 后置处理,在目标方法执行以后执行
* @param joinPoint 接受对象的参数
*/
@AfterReturning("mypointcut()")
public void afterreturing(JoinPoint joinPoint){
System.out.println("后置通知处理");
System.out.println("后置处理的方法"+joinPoint.getSignature().toString());
}
/**
* 环绕处理,在目标方法执行前后都可以进行方法的增强
* @param joinPoint proceedingJoinPoint是JoinPoint的子接口(必须为子接口)
* @return 返回值必须是个Object
* @throws Throwable
*/
@Around("mypointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕处理开始");
//执行目标方法
Object object = joinPoint.proceed();
System.out.println("环绕处理结束");
return object;
}
/**
* 异常信息处理,AOP中很重要的一个部分,一般用于异常的记录和处理
* @param e
*/
@AfterThrowing(value = "mypointcut()",throwing = "e")
public void expect(Throwable e){
System.out.println("异常信息接收并处理,异常信息为:"+e.getMessage());
}
/**
* 后置处理(最终),与前面的后置处理不同的是
* 前一个是要目标方法完整执行完才可以运行,如果目标方法运行错误或有其它因素无法正常执行下去
* 则无法执行后置处理
* 但是这一个无论发生异常一定会执行,有点像finally的作用
*/
@After("mypointcut()")
public void after(){
System.out.println("最终通知:释放资源与数据关闭");
}
}
三、UserDao类
package org.example.AspectJNotes;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
public String finduser(String s){
s = "测试";
System.out.println("目标方法运行成功");
return s;
}
}
四、App类
package org.example.AspectJNotes;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main( String[] args ){
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("AspectJNotesXml.xml");
UserDao userDao = (UserDao)applicationContext.getBean("userDao");
userDao.finduser("123");
}
}
成功编译出现结果