Rumah > Java > javaTutorial > teks badan

Springboot menggunakan spel digabungkan dengan aop untuk merealisasikan pemindahan parameter dinamik

PHPz
Lepaskan: 2023-05-16 11:49:06
ke hadapan
1633 orang telah melayarinya

Pengenalan kepada ungkapan SpEl

Sebelum anda memulakan pengekodan secara rasmi, mari kita fahami ungkapan SpEl (Spring Expression Language), yang merupakan alat yang berkuasa dalam rangka Spring.

SpEl boleh digunakan dalam Bina ungkapan kompleks, akses sifat objek, kaedah objek panggilan, dll. semasa masa jalan

Berikan contoh mudah untuk memudahkan pemahaman, seperti berikut

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

Melalui kes di atas, ia tidak sukar. untuk memahami, apa yang dipanggil SpEl pada asasnya adalah ungkapan analitikal

Mereka yang berminat dengan ungkapan SpEl boleh menyemak sendiri artikel ini

Contoh: SpEl digabungkan dengan transmisi dinamik AOP Rujuk

untuk memahami secara ringkas ungkapan SpEl, kemudian kita akan mula mengekod secara langsung

Mula-mula memperkenalkan kebergantungan pom yang diperlukan kebergantungan, dan SpEl sendiri disokong oleh Spring, jadi Tiada pengenalan tambahan diperlukan

<dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Salin selepas log masuk

Tentukan kelas alat 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();
    }
}
Salin selepas log masuk

Tentukan anotasi dengan parameter SpelGetParm

rreee

Tentukan anotasi dengan parameter SpelGetParmAop

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

    String parm() default "";
    
}
Salin selepas log masuk

Di atas pada dasarnya telah melaksanakan fungsi teras kes Seterusnya, kita boleh menggunakan anotasi ini untuk mentakrifkan Pengguna entiti

@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;
    }
Salin selepas log masuk

Kita boleh menggunakan anotasi ini dengan. parameter terus dalam UserController

@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;

}
Salin selepas log masuk

Permintaan terakhir

Springboot menggunakan spel digabungkan dengan aop untuk merealisasikan pemindahan parameter dinamik

Springboot menggunakan spel digabungkan dengan aop untuk merealisasikan pemindahan parameter dinamikIa boleh dilihat bahawa aspek berjaya memperoleh nilai nama daripada entiti "Zhang San".

Atas ialah kandungan terperinci Springboot menggunakan spel digabungkan dengan aop untuk merealisasikan pemindahan parameter dinamik. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:yisu.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan