使用Aspect快速实现一个自定义注解

举报
KevinQ 发表于 2023/04/19 11:28:51 2023/04/19
【摘要】 最近写东西觉得将示例放前面比较好。 代码前置重点:切面类使用@Configuration, @Aspect注解切面类主要方法使用@Before, @After, @AfterReturning, @AfterThrowing, @Around等做切入使用的类需要使用@Resource方法注入才会生效。@Aspect@Configuration public class PrintBefor...

最近写东西觉得将示例放前面比较好。

代码前置

重点:

  1. 切面类使用@Configuration, @Aspect注解
  2. 切面类主要方法使用@Before, @After, @AfterReturning, @AfterThrowing, @Around等做切入
  3. 使用的类需要使用@Resource方法注入才会生效。
@Aspect
@Configuration  
public class PrintBeforeMethodAspect {  
    @Around("@annotation(PrintBeforeMethod)")  
    public void printBefore(ProceedingJoinPoint joinPoint) throws Throwable {  
        System.out.println("before method");  
        joinPoint.proceed();  
        System.out.println("after method");  
    }  
}
@Resource  
Test testService;

@RequestMapping("/aspect/test")  
public Object aspectTest() {  
    testService.test();  
    return "执行完毕";  
}

起因

最近有个需要,需要给系统增加多租户功能,需要用到切面编程,使用到@Aspect, 分享一下

@Aspect介绍

@Aspect注解用于标注一个类为切面类。切面类是用来实现AOP(Aspect Oriented Programming)的重要组成部分。

@Aspect注解会告诉Spring框架,这个类包含切面逻辑,需要进行AOP处理。在注解的类中,可以定义切面方法,实现对其他方法的拦截和增强。

常用的切面方法有:

  1. @Before - 在目标方法执行前执行的方法,属于前置增强。
  2. @After - 在目标方法执行后执行的方法,属于后置增强。
  3. @AfterReturning -在目标方法正常完成后执行的方法,属于返回增强。
  4. @AfterThrowing - 在目标方法出现异常后执行的方法,属于异常增强。
  5. @Around - 可以在目标方法前后执行自定义的方法,实现织入增强。 可以有参数JoinPoint,用于获知织入点的方法签名等信息。

@Aspect注解的使用使得AOP可以针对业务层中的各个方法进行权限控制,性能监控,事务处理等操作,从而提高了系统的层次性和健壮性。

完整的实现样例

我是搭配注解来使用的

自定义注解

package com.kevinq.aspect;  
  
import java.lang.annotation.*;  
  
/**  
 * @author qww  
 * 2023/4/15 11:24 */
@Target({ElementType.METHOD})  
@Retention(RetentionPolicy.RUNTIME)  
@Inherited  
public @interface PrintBeforeMethod {  
  
  
}

切面,主要程序:(注意,切面类上带有@Configuration 注解)

package com.kevinq.aspect;  
  
//import org.aspectj.lang.ProceedingJoinPoint;  
import org.aspectj.lang.ProceedingJoinPoint;  
import org.aspectj.lang.annotation.Around;  
import org.aspectj.lang.annotation.Aspect;  
import org.aspectj.lang.annotation.Before;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.stereotype.Component;  
  
/**  
 * @author qww  
 * 2023/4/15 11:27 */
@Aspect  
@Configuration  
public class PrintBeforeMethodAspect {  
  
    @Around("@annotation(PrintBeforeMethod)")  
    public void printBefore(ProceedingJoinPoint joinPoint) throws Throwable {  
        System.out.println("before method");  
        joinPoint.proceed();  
        System.out.println("after method");  
    }  
  
}

调用方式:

增加注解

@Service  
public class TestService implements Test{  
  
    @Override  
    @PrintBeforeMethod    
    public void test() {  
        System.out.println("执行test方法");  
    }  
}

调用方法

@Resource  
Test testService;

@RequestMapping("/aspect/test")  
public Object aspectTest() {  
    testService.test();  
    return "执行完毕";  
}

值得注意的是,因为使用的@Configuration来注入,所以需要使用@Resource这种方法来实例化调用,用new TestService()无效。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。