【JavaSpring】Aop的通知类型,获取数据

AOP 通知描述了抽取的共性功能,根据共性功能抽取的位置不同,最终运行代码时要将其加入到合理的位置

前置通知

@Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }

    @Before("pt()")
    public void before() {
        System.out.println("before advice");
    }

后置通知

@Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }

@After("pt()")
    public void after() {
        System.out.println("after advice");
    }

环绕通知(获取异常和返回值)

无对原始操作的调用

显然原始方法不执行了

 @Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }
 
@Around("pt()")
    public void around() {
        System.out.println("around before advice");
        System.out.println("around after advice");
    }

 

加上对原始操作的调用

无返回值

 @Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }
 
@Around("pt()")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice");
        pjp.proceed();
        System.out.println("around after advice");
    }

如果有返回值

@Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice");
        Object obj=pjp.proceed();
        System.out.println("around after advice");
        return obj;
    }

返回后通知(获取返回值)

成功运行后执行

  @Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }

@AfterReturning("pt()")
    public void afterReturning() {
        System.out.println("afterReturning advice");
    }

和后置通知的区别

如果抛出异常,AfterReturning不运行,但After正常运行 

抛出异常后通知(获取异常)

@Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }
 
@AfterThrowing("pt()")
    public void afterThrowing() {
        System.out.println("afterThrowing advice");
    }

测试(通知类型,如果想看看效果,直接复制) 

package org.example.dao.impl;

import org.example.dao.BookDao;
import org.springframework.stereotype.Repository;

@Repository
public class BookDaoImpl implements BookDao {

    public void save() {
        System.out.println("book dao save");
    }


    public void update() {
        System.out.println("book dao update");
    }

    public void delete() {
        System.out.println("book dao delete");
    }

    public int select() {
        System.out.println("book dao select");
        return 100;
    }
}
package org.example.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("org.example")
@EnableAspectJAutoProxy//有用注解开发的AOP
public class SpringConfig {
}
package org.example.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect//当作Aop处理
public class MyAdvice {
    @Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }

    @Before("pt()")
    public void before() {
        System.out.println("before advice");
    }

    @After("pt()")
    public void after() {
        System.out.println("after advice");
    }

    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice");
        Object obj = pjp.proceed();
        System.out.println("around after advice");
        return obj;
    }

    @AfterReturning("pt()")
    public void afterReturning() {
        System.out.println("afterReturning advice");
    }

    @AfterThrowing("pt()")
    public void afterThrowing() {
        System.out.println("afterThrowing advice");
    }
}
package org.example.dao;

public interface BookDao {
    void save();
    void update();
    int select();
}
package org.example;

import org.example.config.SpringConfig;
import org.example.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext ctx=new AnnotationConfigApplicationContext(SpringConfig.class);
        BookDao bookDao=ctx.getBean(BookDao.class);
        bookDao.update();
    }
}

测试(获取参数,JoinPoint必须是第一位)

package org.example.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
@Aspect//当作Aop处理
public class MyAdvice {
    @Pointcut("execution(* org.example.dao.BookDao.findName(..))")
    private void pt() {
    }

    @Before("pt()")
    public void before(JoinPoint jp) {
        Object[] args = jp.getArgs();
        System.out.println("before advice:" + Arrays.toString(args));
    }

    @After("pt()")
    public void after(JoinPoint jp) {
        Object[] args = jp.getArgs();
        System.out.println("after advice:" + Arrays.toString(args));
    }

    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice");
        Object obj = pjp.proceed();
        Object[] args = pjp.getArgs();
        System.out.println("around after advice:" + Arrays.toString(args));
        return obj;
    }

    @AfterReturning(value = "pt()", returning = "res")
    public void afterReturning(Object res) {
        System.out.println("afterReturning advice:" + res);
    }

    @AfterThrowing(value = "pt()", throwing = "t")
    public void afterThrowing(Throwable t) {
        System.out.println("afterThrowing advice"+t);
    }
}
package org.example.dao;

public interface BookDao {

    String findName(int id);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
具体代码实现需要结合具体的业务场景和代码架构来实现,下面是一份基于Spring AOP的伪代码示例: ```java // 1. 创建切面类,用于记录数据变化 @Aspect @Component public class DataChangeAspect { @Autowired private DataChangeLogService dataChangeLogService; // 2. 定义切入点,匹配需要记录数据变化的方法 @Pointcut("execution(* com.example.service.*.*(..))") public void dataChangePointcut() {} // 3. 定义前置通知,记录方法调用前的数据 @Before("dataChangePointcut()") public void beforeDataChange(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); // 通过args参数获取方法调用前的数据 // ... // 记录数据变化 dataChangeLogService.logDataChange(args, DataChangeType.CREATE); } // 4. 定义后置通知,记录方法调用后的数据 @AfterReturning(pointcut = "dataChangePointcut()", returning = "result") public void afterDataChange(JoinPoint joinPoint, Object result) { // 通过result参数获取方法调用后的数据 // ... // 记录数据变化 dataChangeLogService.logDataChange(result, DataChangeType.UPDATE); } // 5. 定义异常通知,记录方法调用异常的数据 @AfterThrowing(pointcut = "dataChangePointcut()", throwing = "ex") public void exceptionDataChange(JoinPoint joinPoint, Exception ex) { Object[] args = joinPoint.getArgs(); // 通过args参数获取方法调用前的数据 // ... // 记录数据变化 dataChangeLogService.logDataChange(args, DataChangeType.DELETE, ex.getMessage()); } } // 6. 创建数据变化日志服务类 @Service public class DataChangeLogService { public void logDataChange(Object data, DataChangeType type) { // 记录数据变化 // ... } public void logDataChange(Object data, DataChangeType type, String message) { // 记录数据变化和异常信息 // ... } } // 7. 创建数据变化类型枚举类 public enum DataChangeType { CREATE, UPDATE, DELETE } ``` 在这份代码中,我们创建一个切面类DataChangeAspect,用于记录需要进行数据变化记录的方法调用,并在其中定义了前置通知、后置通知异常通知,用于分别记录方法调用前后和异常情况下的数据变化。我们还需要创建一个数据变化日志服务类DataChangeLogService,用于具体的数据变化记录操作。最后,我们还需要定义一个数据变化类型枚举类DataChangeType,用于记录数据变化的类型。 需要注意的是,这份代码只是一个示例,具体实现需要根据具体业务场景和代码架构进行调整。而且在实现过程中,也需要考虑到数据安全和隐私保护的问题,避免敏感数据的泄露。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岩塘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值