Maison > Java > javaDidacticiel > Springboot implémente le transfert dynamique de paramètres via spel combiné avec aop

Springboot implémente le transfert dynamique de paramètres via spel combiné avec aop

PHPz
Libérer: 2023-05-16 11:49:06
avant
1680 Les gens l'ont consulté

Introduction aux expressions SpEl

Avant de commencer à écrire le code, comprenez d'abord les expressions SpEl (Spring Expression Language), qui sont un outil puissant dans le framework Spring

Spring peut construire des expressions complexes et accéder aux objets au moment de l'exécution via les attributs SpEl, appels de méthode objet, etc.

Un exemple simple pour faciliter la compréhension, comme suit

//定义了一个表达式
String expressionStr = "1+1";
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(expressionStr);
Integer val = expression.getValue(Integer.class);
System.out.println(expressionStr + "的结果是:" + val);
Copier après la connexion

Grâce aux cas ci-dessus, il n'est pas difficile de comprendre que ce qu'on appelle SpEl est en fait une expression analytique.

À propos des expressions SpEl Si vous Si vous êtes intéressé, vous pouvez vérifier les informations par vous-même. Cet article n'en discutera pas en détail

Exemple : SpEl combiné avec le transfert de paramètres dynamiques AOP

Ayez une brève compréhension des expressions SpEl, puis commençons directement par le code.

Introduisez d'abord la dépendance pom nécessaire, en fait, uniquement la dépendance aop, SpEl lui-même est pris en charge par Spring, il n'est donc pas nécessaire de l'introduire en plus

<dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Copier après la connexion

Définir une classe d'outils SpEl SpelUtil

public class SpelUtil {
    /**
     * 用于SpEL表达式解析.
     */
    private static final SpelExpressionParser parser = new SpelExpressionParser();

    /**
     * 用于获取方法参数定义名字.
     */
    private static final DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();

    /**
     * 解析SpEL表达式
     *
     * @param spELStr
     * @param joinPoint
     * @return
     */
    public static String generateKeyBySpEL(String spELStr, ProceedingJoinPoint joinPoint) {
        // 通过joinPoint获取被注解方法
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        // 使用Spring的DefaultParameterNameDiscoverer获取方法形参名数组
        String[] paramNames = nameDiscoverer.getParameterNames(method);
        // 解析过后的Spring表达式对象
        Expression expression = parser.parseExpression(spELStr);
        // Spring的表达式上下文对象
        EvaluationContext context = new StandardEvaluationContext();
        // 通过joinPoint获取被注解方法的形参
        Object[] args = joinPoint.getArgs();
        // 给上下文赋值
        for (int i = 0; i < args.length; i++) {
            context.setVariable(paramNames[i], args[i]);
        }
        // 表达式从上下文中计算出实际参数值
        /*如:
            @annotation(key="#user.name")
            method(User user)
             那么就可以解析出方法形参的某属性值,return “xiaoming”;
          */
        return expression.getValue(context).toString();
    }
}
Copier après la connexion

Définir une annotation basée sur des paramètres. SpelGetParm

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SpelGetParm {

    String parm() default "";
    
}
Copier après la connexion

Définir une annotation basée sur des paramètres SpelGetParmAop

@Aspect
@Slf4j
@Component
public class SpelGetParmAop {

    @PostConstruct
    public void init() {
        log.info("SpelGetParm init ......");
    }
    /**
     * 拦截加了SpelGetParm注解的方法请求
     *
     * @param joinPoint
     * @param spelGetParm
     * @return
     * @throws Throwable
     */
    @Around("@annotation(spelGetParm)")
    public Object beforeInvoce(ProceedingJoinPoint joinPoint, SpelGetParm spelGetParm) throws Throwable {
        Object result = null;
        // 方法名
        String methodName = joinPoint.getSignature().getName();
        //获取动态参数
        String parm = SpelUtil.generateKeyBySpEL(spelGetParm.parm(), joinPoint);
        log.info("spel获取动态aop参数: {}", parm);
        try {
            log.info("执行目标方法: {} ==>>开始......", methodName);
            result = joinPoint.proceed();
            log.info("执行目标方法: {} ==>>结束......", methodName);
            // 返回通知
            log.info("目标方法 " + methodName + " 执行结果 " + result);
        } finally {

        }
        // 后置通知
        log.info("目标方法 " + methodName + " 结束");
        return result;
    }
Copier après la connexion

Ce qui précède a essentiellement implémenté les fonctions de base du cas. Ensuite, nous pouvons utiliser cette annotation pour définir une entité User

@Getter
@Setter
@NoArgsConstructor
@JsonSerialize
@JsonInclude(Include.NON_NULL)
public class User implements Serializable {
    private static final long serialVersionUID = -7229987827039544092L;

    private String name;
    private Long id;

}
Copier après la connexion

Nous pouvons directement utiliser cette annotation avec des paramètres dans. le UserController

@CrossOrigin
@RestController
@RequestMapping("/user")
public class UserController {
    @PostMapping("/param")
    @SpelGetParm(parm = "#user.name")
    public R repeat(@RequestBody User user) {
        return R.success(user);
    }
}
Copier après la connexion

Enfin la demande

Springboot implémente le transfert dynamique de paramètres via spel combiné avec aop

Springboot implémente le transfert dynamique de paramètres via spel combiné avec aopOn peut voir que l'aspect a obtenu avec succès la valeur du nom de l'entité "Zhang San".

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal