Spring AOP如何在注解上使用SPEL表达式注入对象

 更新时间:2022年02月17日 14:37:59   作者:低脂肪  
这篇文章主要介绍了Spring AOP如何在注解上使用SPEL表达式注入对象,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

在注解上使用SPEL表达式注入对象

场景描述

在平时开发中,我们经常通过定义一些注解,进行轻量级开发。

今天主要研究的内容是关于如何在注解上通过spel表达式注入对象,以此调用注入对象的具体业务处理逻辑,然后在通过对表达式的解析,进而获取该业务逻辑处理的结果,类似于Spring Security中的@PreAuthorize, @PreAuthorize, @PostAuthorize等注解,本次场景案例以模仿@PreAuthorize注解进行分析。

具体案例

定义@SpelPreAuthorize注解,对标@PreAuthorize

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SpelPreAuthorize {
    String value() default "";
}

定义具体业务逻辑处理类

import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Component("ps")
public class PermissionService {    
    public boolean hasPermission(String permission) {
        List<String> allPermissions = Arrays.asList("user:save", "user:delete", "user:edit");
        return allPermissions.contains(permission);
    }     
}

定义切面

  • 通过@Before注解定义前置切面
  • 通过注入spelExpressionParser解析器,用于解析spel表达式
  • 实例化EvaluationContext对象(默认实现tandardEvaluationContext),解析表达式,注入上下文信息,执行具体业务
import com.czf.ebao.data.spel.annoation.SpelPreAuthorize;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class SpelPreAuthorizeAspect {
    /**
     * 注入spring bean 工厂
     */
    @Autowired
    private DefaultListableBeanFactory defaultListableBeanFactory;
    @Before("@annotation(spelPreAuthorize)")
    public void perAuthorize(JoinPoint point, SpelPreAuthorize spelPreAuthorize) {
        String permission = spelPreAuthorize.value();
        // 实例化spel表达式解析器
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        // 解析表达式内容
        Expression expression = spelExpressionParser.parseExpression(permission);
        // 声明StandardEvaluationContext对象,用于设置上下文对象。
        StandardEvaluationContext context = new StandardEvaluationContext();
        context.setBeanResolver(new BeanFactoryResolver(defaultListableBeanFactory));
        Boolean result = expression.getValue(context, Boolean.class);
        if (!result) {
            throw new RuntimeException("该用户无访问权限");
        }
    }
}

定义测试类

import com.czf.ebao.data.spel.annoation.SpelPreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/spel")
public class SpelController {
    
    @GetMapping("/hello")
    @SpelPreAuthorize("@pms.hasPermission('user:hello')")
    public String sayHello() {
        return "hello";
    }
}

补充

通配符匹配

// import org.springframework.util.PatternMatchUtils
List<String> allPermissions = Arrays.asList("user:save", "user:delete", "user:edit");
return allPermissions.stream().anyMatch(item -> PatternMatchUtils.simpleMatch(permission, item));

Spring属性注入方式之SPEL表达式

<bean id="categroy" class="com.test.inject.Category" p:cateName="服装"></bean>
<bean id="calculate" class="com.test.inject.PriceCalculate"></bean>
<bean id="product" class="com.test.inject.Product" p:name="A21的T恤" p:categroy-ref="categroy">
  <property name="price" value="#{calculate.calPrice()}"></property>
</bean>

spel表达式的好处就是,我们可以使用定义好的某个类中的方法来产生值,然后注入给所需要的对象使用

比较适用于比较复杂的bean注入

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java实现带GUI的气泡诗词效果

    Java实现带GUI的气泡诗词效果

    这篇文章主要为大家介绍了如何利用Java实现带GUI的气泡诗词效果,文中的示例代码讲解详细,对我们学习Java有一定帮助,感兴趣的可以了解一下
    2022-12-12
  • mybatis清除一级缓存的几种方式

    mybatis清除一级缓存的几种方式

    这篇文章主要介绍了mybatis清除一级缓存的几种方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Java中如何模拟HTTP请求并验证功能

    Java中如何模拟HTTP请求并验证功能

    要模拟HTTP请求并验证功能,你可以使用Spring Boot提供的MockMvc工具,它允许我们在没有实际启动HTTP服务器的情况下测试Spring MVC控制器,下面给大家分享如何模拟HTTP请求并验证功能,感兴趣的朋友一起看看吧
    2024-05-05
  • 在SpringBoot中定义和读取自定义配置的方法步骤

    在SpringBoot中定义和读取自定义配置的方法步骤

    在Spring Boot中定义和读取自定义配置是日常开发中常见的需求,它允许我们以灵活的方式管理应用的配置信息,无论是通过外部配置文件还是通过环境变量,本文是一个详细的步骤说明,包括示例代码,需要的朋友可以参考下
    2024-10-10
  • 使用Mybatis的PageHelper分页工具的教程详解

    使用Mybatis的PageHelper分页工具的教程详解

    这篇文章主要介绍了使用Mybatis的PageHelper分页工具的教程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 概述Java的struts2框架

    概述Java的struts2框架

    本篇文章主要对struts2框架概念、优缺点进行简要概述。相信会对大家学习Java有所帮助,需要的朋友一起来看下吧
    2016-12-12
  • Spring注解驱动之BeanDefinitionRegistryPostProcessor原理解析

    Spring注解驱动之BeanDefinitionRegistryPostProcessor原理解析

    这篇文章主要介绍了Spring注解驱动之BeanDefinitionRegistryPostProcessor原理,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • Go Java算法之找不同示例详解

    Go Java算法之找不同示例详解

    这篇文章主要为大家介绍了Go Java算法之找不同示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • MybatisPlus自带的queryWrapper实现时间倒序方式

    MybatisPlus自带的queryWrapper实现时间倒序方式

    这篇文章主要介绍了MybatisPlus自带的queryWrapper实现时间倒序方式,具有很好的参考价值,希望对的有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • mybatis取别名typeAliases标签的位置放错导致报错的解决

    mybatis取别名typeAliases标签的位置放错导致报错的解决

    这篇文章主要介绍了mybatis取别名typeAliases标签的位置放错导致报错的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论