Table of Contents
Introduction to SpEl expressions
Example: SpEl combined with AOP dynamic transmission Reference
Home Java javaTutorial Springboot uses spel combined with aop to realize dynamic parameter transfer

Springboot uses spel combined with aop to realize dynamic parameter transfer

May 16, 2023 am 11:49 AM
aop springboot spel

Introduction to SpEl expressions

Before starting to write the code, let’s first understand SpEl (Spring Expression Language) expressions, which are a powerful tool in the Spring framework.

Spring can use SpEl to Construct complex expressions, access object properties, call object methods, etc. during runtime.

Give a simple example to facilitate understanding, as follows

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

Through the above cases, it is not difficult to understand, the so-called SpEl is essentially a parsing expression.

If you are interested in SpEl expression, you can check the information by yourself. This article will not discuss it in detail.

Example: SpEl combined with AOP dynamic transmission Reference

Have a brief understanding of SpEl expressions, then we will start coding directly.

First introduce the necessary pom dependencies. In fact, there are only aop dependencies, and SpEl itself is supported by Spring, so No additional introduction is required.

<dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Copy after login

Define a SpEl tool class 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();
    }
}
Copy after login

Define a parameter-based annotation SpelGetParm

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

    String parm() default "";
    
}
Copy after login

Define a parameter-based annotation 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;
    }
Copy after login

The core functions of the case have been basically implemented above. Next, we can use this annotation to define an entity 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;

}
Copy after login

We can directly use this annotation with parameters in the UserController

@CrossOrigin
@RestController
@RequestMapping("/user")
public class UserController {
    @PostMapping("/param")
    @SpelGetParm(parm = "#user.name")
    public R repeat(@RequestBody User user) {
        return R.success(user);
    }
}
Copy after login

Last request

Springboot uses spel combined with aop to realize dynamic parameter transfer

Springboot uses spel combined with aop to realize dynamic parameter transferIt can be seen that the aspect successfully obtained the name value of the entity "Zhang San".

The above is the detailed content of Springboot uses spel combined with aop to realize dynamic parameter transfer. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot Article

Hot Article

Hot Article Tags

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How Springboot integrates Jasypt to implement configuration file encryption How Springboot integrates Jasypt to implement configuration file encryption Jun 01, 2023 am 08:55 AM

How Springboot integrates Jasypt to implement configuration file encryption

How SpringBoot integrates Redisson to implement delay queue How SpringBoot integrates Redisson to implement delay queue May 30, 2023 pm 02:40 PM

How SpringBoot integrates Redisson to implement delay queue

How to use Redis to implement distributed locks in SpringBoot How to use Redis to implement distributed locks in SpringBoot Jun 03, 2023 am 08:16 AM

How to use Redis to implement distributed locks in SpringBoot

How to solve the problem that springboot cannot access the file after reading it into a jar package How to solve the problem that springboot cannot access the file after reading it into a jar package Jun 03, 2023 pm 04:38 PM

How to solve the problem that springboot cannot access the file after reading it into a jar package

Comparison and difference analysis between SpringBoot and SpringMVC Comparison and difference analysis between SpringBoot and SpringMVC Dec 29, 2023 am 11:02 AM

Comparison and difference analysis between SpringBoot and SpringMVC

How SpringBoot customizes Redis to implement cache serialization How SpringBoot customizes Redis to implement cache serialization Jun 03, 2023 am 11:32 AM

How SpringBoot customizes Redis to implement cache serialization

How to get the value in application.yml in springboot How to get the value in application.yml in springboot Jun 03, 2023 pm 06:43 PM

How to get the value in application.yml in springboot

How to implement Springboot+Mybatis-plus without using SQL statements to add multiple tables How to implement Springboot+Mybatis-plus without using SQL statements to add multiple tables Jun 02, 2023 am 11:07 AM

How to implement Springboot+Mybatis-plus without using SQL statements to add multiple tables

See all articles