Heim > Java > javaLernprogramm > Springboot implementiert die dynamische Parameterübertragung durch Spel in Kombination mit AOP

Springboot implementiert die dynamische Parameterübertragung durch Spel in Kombination mit AOP

PHPz
Freigeben: 2023-05-16 11:49:06
nach vorne
1681 Leute haben es durchsucht

Einführung in SpEl-Ausdrücke

Bevor Sie mit dem Schreiben des Codes beginnen, machen Sie sich zunächst mit SpEl-Ausdrücken (Spring Expression Language) vertraut, die ein leistungsstarkes Werkzeug im Spring-Framework sind.

Spring kann über SpEl-Attribute komplexe Ausdrücke erstellen und zur Laufzeit auf Objekte zugreifen. Objektmethodenaufrufe usw.

Ein einfaches Beispiel zum leichteren Verständnis, wie folgt:

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

Anhand der oben genannten Fälle ist es nicht schwer zu verstehen, dass der sogenannte SpEl tatsächlich ein analytischer Ausdruck ist.

Über SpEl-Ausdrücke Wenn Sie Wenn Sie interessiert sind, können Sie die Informationen selbst überprüfen.

Beispiel: SpEl kombiniert mit der dynamischen Parameterübertragung von AOP

Haben Sie ein kurzes Verständnis der SpEl-Ausdrücke, dann beginnen wir direkt mit dem Code.

Führen Sie zunächst die erforderliche Pom-Abhängigkeit ein, eigentlich nur die AOP-Abhängigkeit. SpEl selbst wird von Spring unterstützt, daher besteht keine Notwendigkeit, sie zusätzlich einzuführen SpelGetParm

<dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Nach dem Login kopieren

Definieren Sie eine parameterbasierte Annotation SpelGetParmAop

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();
    }
}
Nach dem Login kopieren

Das Obige hat im Grunde die Kernfunktionen des Falls implementiert. Als nächstes können wir diese Annotation verwenden, um eine Entität zu definieren User

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

    String parm() default "";
    
}
Nach dem Login kopieren

Wir können diese Annotation direkt mit Parametern verwenden der UserController

@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;
    }
Nach dem Login kopieren

Endlich anfordern

Es ist ersichtlich, dass der Aspekt den Namenswert der Entität „Zhang San“ erfolgreich erhalten hat.Springboot implementiert die dynamische Parameterübertragung durch Spel in Kombination mit AOP

Das obige ist der detaillierte Inhalt vonSpringboot implementiert die dynamische Parameterübertragung durch Spel in Kombination mit AOP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage