Springboot如何使用注解实现AOP


前言

在一些场景下,我们需要在执行某些方法或者某些代码时,预先执行或者后置执行特定的一些方法,但是我们不想在代码里复写,我们不想在代码里将这些指定的方法写入进去,而是通过抽离的方式,这种场景下aop切面可以帮助我们完成这种操作


提示:以下是本篇文章正文内容,下面案例可供参考

一、AOP是什么?

spring两大核心包括ioc和aop,ioc是控制反转,将对象交由容器进行控制,不用重复的new。
而aop是面向切面编程,aop采用横向抽取机制,取代纵向集成体系的重复性代码。如使用aop实现日志打印,事务管理,安全权限等。

二、代理模式

aop实现在于aop代理。aop代理又分为静态代理和动态代理。

1.什么是代理

为某一个对象创建一个代理对象,程序不直接用原本的对象,而是由创建的代理对象来控制原对象,通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间。

2.静态代理

由程序创建或特定工具自动生成源代码,在程序运行前,代理类的.class文件就已经存在

通过将目标类与代理类实现同一个接口,让代理类持有真实类对象,然后在代理类方法中调用真实类方法,在调用真实类方法的前后添加我们所需要的功能扩展代码来达到增强的目的。

3.动态代理

在程序运行时,运用反射机制动态创建而成,无需手动编写代码

JDK动态代理
CGLIB动态代理(原理:是对指定的业务类生成一个子类,并覆盖其中的业务方法来实现代理)

区别
1.jdk动态代理是基于接口的,jdk动态代理是产生一个新的对象实现接口,包裹实现接口的代理目标类,但是这个实现类有特有的方法,那么代理类不能代理这个方法。
2.cglib动态代理是基于集成的,cglib动态代理是产生一个新的对象继承实现类,也就成了代理目标类的子类,那么实现类特有的方法是会被代理的

问题:spring的aop是使用的jdk动态代理还是cglib动态代理

spring 默认情况下会判断代理类有没有实现接口,实现了就是jdk代理,继承就是cglib代理。在springboot中默认配置为cglib动态代理


三,springboot中如何使用注解来实现aop

1.自定义注解

@Target(ElementType.METHOD)   //定义注解的使用范围为方法
@Retention(RetentionPolicy.RUNTIME )
public @interface SaveHotKey {

}

1.@Target :注解的作用目标

@Target(ElementType.TYPE)作用在接口,类,枚举,注解(如@restcontroller)
@Target(ElementType.FIELD)作用于字段,枚举的常量 @filed
@Target(ElementType.METHOD)作用于方法,@reqestmapping
@Target(ElementType.CONSTRUCTOR)作用于构造函数
@Target(ElementType.PARAMETER)作用于方法参数 @param

2.@Retention 注解保留生命周期

source注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略
class注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期
runtime注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在

2.切面类

业务逻辑,在调用查询接口前,保存一份参数。

@Aspect
@Component
public class SaveHotKeyAspect {

    @Autowired
    private ElasticSearchUtils elasticSearchUtils;

    @Pointcut("@annotation(com.xxxx.cloud.elasticsearch.aop.SaveHotKey)")
    public void checkDataPoint(){

    }

    @Before("checkDataPoint()")  //前置通知
    public void checkBefore(JoinPoint point){
        Object[] args=point.getArgs();
        ResourceQuery query= (ResourceQuery)args[0];
        //存es的热搜词中
        if (StringUtils.isNotBlank(query.getKeyWord())){
            HotKeyWordsPo hotKeyWordsPo = new HotKeyWordsPo();
            hotKeyWordsPo.setId(UUID.randomUUID().toString());
            hotKeyWordsPo.setCreateTime(new Date());
            hotKeyWordsPo.setSearchInput(query.getKeyWord());
            try {
                elasticSearchUtils.addData(hotKeyWordsPo, ESConst.HOT_KEY_INDEX,hotKeyWordsPo.getId());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

/*  @After("checkDataPoint()") //后置通知
    public void checkAfter(){

    }*/
}

1 @Aspect:把当前类标识为一个切面供容器读取

2.@Pointcut:aop切入点,表示在什么条件下触发

3.@annotation:声明以注解的方式来定义切点,注解为SaveHotKey的包路径

4.@Before:前置增强方法的标识,表示在标有注解的方法前执行切面方法

5.其他方式:
除了使用注解方式外,@pointcut中提供匹配规则 execution,写法可以表达为

@Pointcut("execution(* com.xxx.cloud.controller.*.(..))")

总结

execution匹配规则不太熟悉,但是注解方式好像更灵活,可以直接在需要的地方打上注解就完成切面

  • 0
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot可以使用注解实现AOP(面向切面编程)。AOP是一种编程范式,它将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,以便更好地实现模块化和复用性。 在Spring Boot中,可以使用@Aspect注解来定义切面,使用@Pointcut注解来定义切点,使用@Before、@After、@Around等注解来定义通知。通过这些注解的组合,可以实现对方法的前置、后置、环绕等操作。 例如,下面的代码演示了如何使用注解实现AOP: ```java @Aspect @Component public class LogAspect { @Pointcut("execution(* com.example.demo.service.*.*(..))") public void pointcut() {} @Before("pointcut()") public void before(JoinPoint joinPoint) { System.out.println("before " + joinPoint.getSignature().getName()); } @After("pointcut()") public void after(JoinPoint joinPoint) { System.out.println("after " + joinPoint.getSignature().getName()); } @Around("pointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("around before " + joinPoint.getSignature().getName()); Object result = joinPoint.proceed(); System.out.println("around after " + joinPoint.getSignature().getName()); return result; } } ``` 在上面的代码中,@Aspect注解表示这是一个切面类,@Component注解表示这是一个Spring组件。@Pointcut注解定义了切点,这里表示拦截com.example.demo.service包下的所有方法。@Before、@After、@Around注解分别表示前置通知、后置通知、环绕通知,它们的参数是切点表达式。 通过这种方式,我们可以很方便地实现AOP,将横切关注点从业务逻辑中分离出来,提高代码的可维护性和可重用性。 ### 回答2: Spring Boot是一种核心框架Spring的扩展,其自动化配置和默认设置能够降低Spring应用程序的开发难度和复杂性。AOP(面向切面编程)是Spring框架中非常重要的一个特性,它提供了一种方法用于跨越应用程序多个部分进行交叉剖面的分离关注点。Spring Boot使用注解实现AOP,使得切面编程的应用变得更加简单和易于维护。 Spring Boot使用AspectJ注解为Aspect提供了支持。Aspect指定义切面的类,通过使用@Aspect注释标记Aspect。在Aspect中,开发者可以通过使用其他注释来定义切点和通知,以及为方便切面声明添加其他接口方法。 切点是一个表达式,它指定要应用切面的位置,例如在方法前,方法后,异常抛出,或联接点(连接点)。在Spring Boot中,可以使用@Pointcut注释来定义切点表达式。可以将切点表达式定义为公共的或私有的类方法,以便重复使用。 通知是切面类中的方法,它定义了在切点执行时应该执行的行为。Spring Boot支持五种类型的通知注释: - @Before:在方法执行前执行切面代码。 - @AfterReturning:当方法正常返回值后执行切面代码。 - @AfterThrowing:在方法抛出异常后执行切面代码。 - @After:在方法执行后执行切面代码,无论方法执行结果如何。 - @Around:在方法执行前和执行后执行切面代码。 在编写完AOP切面以后,还需要将其纳入到Spring IoC容器中。使用@Component注释将切面类注册为Spring Bean组件,并在应用程序上下文中启用AspectJ自动代理。 总之,使用注释实现AOPSpring Boot中非常重要和受欢迎的特征之一。将重复的代码分离到切面中,确保与业务逻辑分离的代码清晰,可读性和可维护性都得到了极大的提高。 ### 回答3: Spring Boot是一个快速开发的框架,使用起来非常简便,其中注解AOP也是Spring Boot框架中非常常用的一种方式,本文主要介绍Spring Boot如何使用注解实现AOP注解AOPSpring框架提供的一种AOP编程的方式,它可以通过添加@Aspect注解来定义切面,通过添加@Before、@After、@Around等注解来定义具体的增强逻辑。Spring Boot实现AOP时,需要借助于AspectJ框架,同时需要定义切面和切点。 首先,需要在应用程序中添加“spring-boot-starter-aop”依赖,然后定义一个被增强的Bean,并在其上添加需要增强的方法(也可以在类或者方法上添加@Aspect注解)。 然后,需要定义一个切面,并在切面上添加@Before、@After、@Around等注解来定义增强逻辑,通过AspectJ的注解方式,可以实现对方法的调用进行切面操作。 最后,需要通过在启动类中添加@EnableAspectJAutoProxy注解来启用AOP代理自动创建功能。 总而言之,Spring Boot使用注解实现AOP非常简单,只需要添加依赖,定义切面,定义增强逻辑,最后在启动类中启用AOP代理自动创建功能即可。注解AOP可以使得编程更加简单和便捷,同时也能够提高代码的可读性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值