外卖项目--Springboot回顾Day3
外卖项目–Springboot回顾Day3
公共字段自动填充
因为creat_time,create_user,update_time,update_user在每个mapper层中都有,造成了代码冗余并且不利于维护,所以本节使用切面将他们统一处理
思路:
- 自定义注解AutoFill,用于标识需要公共字段自动填充的方法
- 自定义切面类AutoFillAspect,统一拦截加入了AutoFill注解的方法,通过反射为公共字段赋值
- 在Mapper的方法上加入AutoFill注解
技术点:注解,AOP,反射
代码实现:happy:
AutoFill.java
1 | /** |
@Target :指定当前代码会加在什么位置
@Retention :
@Retention
注解在Java中扮演着非常重要的角色,它用于指定自定义注解的保留策略,即定义注解在Java程序中的生命周期。具体来说,@Retention
注解决定了注解信息被保留到什么阶段:是仅保留在源代码中,还是被编译到class文件中,或者是在运行时仍然保留并可被JVM访问。@Retention
注解有一个参数RetentionPolicy
,它是一个枚举类型,包含以下三个值:**
RetentionPolicy.SOURCE
**:- 这是最短的保留策略。注解仅保留在源代码中,不会被编译进class文件,也不会对运行时产生任何影响。
- 这种策略通常用于那些只需要在编译时存在,而在运行时不需要的注解,比如用于生成文档或进行编译时检查的注解。
**
RetentionPolicy.CLASS
**:- 注解会被编译进class文件中,但在运行时不会被JVM保留,因此不能通过反射机制在运行时访问这些注解。
- 这是默认的保留策略,如果自定义注解没有显式指定
@Retention
注解,那么就会采用这种策略。 - 这种策略适用于那些需要在编译时或类加载时通过其他机制(非反射)访问的注解。
**
RetentionPolicy.RUNTIME
**:- 注解会被编译进class文件中,并在运行时被JVM保留,因此可以通过反射机制在运行时访问这些注解。
- 这种策略通常用于那些需要在运行时通过反射读取注解信息的场景,比如实现自定义的注解处理器或框架。
使用
@Retention
注解可以帮助开发者更好地控制注解的生命周期,从而在不同的阶段(编译时、类加载时、运行时)根据需要来访问和处理注解信息。这对于开发框架、库或需要高度灵活性和动态性的应用程序来说尤为重要。
AutoFillAspect.java
1 |
|
- @Pointcut:对哪些包的哪些方法进行拦截
这个注释是一个AspectJ的@Pointcut
注解,用于在面向切面编程(AOP)中定义一个切入点(Pointcut)。切入点是AOP中的一个核心概念,它定义了哪些类的哪些方法将被拦截(或称为“被增强”)以及何时被拦截。具体来说,这个@Pointcut
注解定义了一个特定的切入点表达式,让我们逐步解析这个表达式:
1 |
组成部分
execution( com.sky.mapper.
.*(..))**:
这是切入点表达式的主要部分,使用了
execution
模式匹配器。* com.sky.mapper.*.*(..)
指定了匹配的方法签名。
- 第一个
*
表示匹配任何返回类型。 com.sky.mapper
指定了包名,表示匹配该包及其子包下的类。- 第二个
*
表示匹配com.sky.mapper
包下的任何类。 - 第三个
*
表示匹配任何方法名。 (..)
表示匹配任何数量的参数(包括零个参数)。
- 第一个
总的来说,这部分表达式匹配
com.sky.mapper
包及其子包下所有类的所有方法。
&& @annotation(com.sky.annotation.AutoFill)
:
- 这部分使用了逻辑与(
&&
)操作符来进一步限制匹配的方法。 @annotation(com.sky.annotation.AutoFill)
指定了另一个条件,即被匹配的方法上必须带有@AutoFill
注解,该注解位于com.sky.annotation
包下。- 因此,只有当方法既位于
com.sky.mapper
包或其子包下的类中,又带有@AutoFill
注解时,它才会被这个切入点表达式匹配。
- 这部分使用了逻辑与(
@Before(“autoFillPointCut()”)
用于定义一个前置通知(Before Advice),该通知会在目标方法执行之前运行。当你看到
@Before("autoFillPointCut()")
这样的代码时,它意味着定义了一个前置通知,该通知将会在任何被autoFillPointCut()
切入点表达式匹配的方法执行之前运行。
为什么使用到反射?
因为自动复制填充的表不是都是员工表,所以不可以向下转型成员工表,然后调用set方法直接修改,只能用反射动态调用set进行需改。反射允许程序在运行时动态地访问和操作类的属性和方法。通过使用反射,你可以不知道具体类名的情况下,调用任何对象的任何方法,只要这个方法存在且可访问。