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

目录
  • 在注解上使用SPEL表达式注入对象
    • 场景描述
    • 具体案例
    • 补充
  • Spring属性注入方式之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注入

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

(0)

相关推荐

  • 基于spring @Cacheable 注解的spel表达式解析执行逻辑

    目录 直接进入主题 跟随spring的调用链 直接看 @Cacheable 注解就可以了 接下来看 key获取是在哪里 没有任何逻辑就是一个组装 了解一下@Cacheable的拦截顺序 接下来看 execute方法 再看 重载方法execute 日常使用中spring的 @Cacheable 大家一定不陌生,基于aop机制的缓存实现,并且可以选择cacheManager具体提供缓存的中间件或者进程内缓存,类似于 @Transactional 的transactionManager ,都是提供了一

  • 使用Springboot自定义注解,支持SPEL表达式

    目录 Springboot自定义注解,支持SPEL表达式 1.自定义注解 2.使用AOP拦截方法,解析注解参数 自定义注解结合切面和spel表达式 自定义一个注解 自定义一个service类,在需要拦截的方法上加上@Log注解 写一个自定义切面 pom文件的依赖 测试 增加内容 Springboot自定义注解,支持SPEL表达式 举例,自定义redis模糊删除注解 1.自定义注解 import java.lang.annotation.ElementType; import java.lang.

  • Spring Cache抽象-使用SpEL表达式解析

    目录 Spring Cache抽象-使用SpEL表达式 概述 SpEl表达式 如何让自定义注解支持SpEL表达式 使用方法 使用案例 1.准备 2.自定义注解 3.定义AOP拦截注解对方法增强进行读写缓存 4.测试 Spring Cache抽象-使用SpEL表达式 概述 在Spring Cache注解属性中(比如key,condition和unless),Spring的缓存抽象使用了SpEl表达式,从而提供了属性值的动态生成及足够的灵活性. 下面的代码根据用户的userCode进行缓存,对于ke

  • spring之SpEL表达式详解

    目录 1.什么是SpEL表达式 2.SpEL表达式语言入门程序 (1)xml配置的方式 (2)采用注解的方式 3.分析器 4.使用SpEL表达式调用方法 (1)使用SpEL调用普通方法 (2)使用SpEL调用构造方法 (3)使用SpEL调用静态方法 6.使用SpEL表达式调用变量和函数 (1)#变量的表达式使用 (2)#root表达式的使用 (3)访问系统的属性和环境 7.使用SpEL表达式中的运算符 1.什么是SpEL表达式 SpEL表达式语言是一种表达式语言,是一种可以与一个基于spring

  • 使用Spring Expression Language (SpEL)全面解析表达式

    目录 Spring Expression Language (SpEL) 1.环境准备 2.SpEL示例应用 3.小结 Spring表达式语言SpEL SpEL:字面量 SpEL:引用 Bean.属性和方法 SpEL支持的运算符号 示例-基于xml的方式 Spring Expression Language (SpEL) 是强大的表达式语言,支持查询.操作运行时对象图,以及解析逻辑.算术表达式.SpEL可以独立使用,无论你是否使用Spring框架. 本文尝试通过多个示例使用SpEL,探索其强大能

  • Spring表达式语言SpEL用法详解

    这篇文章主要介绍了spring表达式语言SpEL用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 (1)spring表达式语言是一个支持运行时查询和操作对象图得我强大表达式语言. (2)语言类似于EL:SpEL使用#{...}作为定界符.所有在大括号中的字符串均被认为是SpEL. (3)SpEL为bean的属性进行动态赋值提供了便利. (4)通过SpEL可以实现: 通过Bean的id对Bean进行引用 调用方法及引用对象的属性 计算表达式

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

    目录 在注解上使用SPEL表达式注入对象 场景描述 具体案例 补充 Spring属性注入方式之SPEL表达式 在注解上使用SPEL表达式注入对象 场景描述 在平时开发中,我们经常通过定义一些注解,进行轻量级开发. 今天主要研究的内容是关于如何在注解上通过spel表达式注入对象,以此调用注入对象的具体业务处理逻辑,然后在通过对表达式的解析,进而获取该业务逻辑处理的结果,类似于Spring Security中的@PreAuthorize, @PreAuthorize, @PostAuthorize等

  • Spring Aop之AspectJ注解配置实现日志管理的方法

    最近项目要做一个日志功能,我用Spring Aop的注解方式来实现. 创建日志注解 package com.wyj.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lan

  • Spring AOP如何实现注解式的Mybatis多数据源切换详解

    一.为什么要使用多数据源切换? 多数据源切换是为了满足什么业务场景?正常情况下,一个微服务或者说一个WEB项目,在使用Mybatis作为数据库链接和操作框架的情况下通常只需要构建一个系统库,在该系统库创建业务表来满足需求,当然也有分为测试库和正式库dev/prod,不过这俩库的切换是使用配置文件进行切分的,在项目启动时或者打成maven JAR包指定environment-dev.properties或者environment-prod.properties. 那么当程序运行过程中,比如一个co

  • Spring AOP 实现自定义注解的示例

    自工作后,除了一些小项目配置事务使用过 AOP,真正自己写 AOP 机会很少,另一方面在工作后还没有写过自定义注解,一直很好奇注解是怎么实现他想要的功能的,刚好做项目的时候,经常有人日志打得不够全,经常出现问题了,查日志的才发现忘记打了,所以趁此机会,搜了一些资料,用 AOP + 自定义注解,实现请求拦截,自定义打日志,玩一下这两个东西,以下是自己完的一个小例子,也供需要的同学参考. 1. 注解如下: package cn.bridgeli.demo.annotation;   import j

  • Spring实战之Bean定义中的SpEL表达式语言支持操作示例

    本文实例讲述了Spring实战之Bean定义中的SpEL表达式语言支持操作.分享给大家供大家参考,具体如下: 一 配置 <?xml version="1.0" encoding="GBK"?> <!-- 指定Spring配置文件的根元素和Schema 导入p:命名空间和util:命名空间的元素 --> <beans xmlns="http://www.springframework.org/schema/beans"

  • 详解使用Spring AOP和自定义注解进行参数检查

    引言 使用SpringMVC作为Controller层进行Web开发时,经常会需要对Controller中的方法进行参数检查.本来SpringMVC自带@Valid和@Validated两个注解可用来检查参数,但只能检查参数是bean的情况,对于参数是String或者Long类型的就不适用了,而且有时候这两个注解又突然失效了(没有仔细去调查过原因),对此,可以利用Spring的AOP和自定义注解,自己写一个参数校验的功能. 代码示例 注意:本节代码只是一个演示,给出一个可行的思路,并非完整的解决

  • Spring AOP使用@Aspect注解 面向切面实现日志横切的操作

    引言: AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型. 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率. 在Spring AOP中业务逻辑仅仅只关注业务本身,将日志记录,性能统计,安全控制,事务处理,异

  • Spring AOP 切面@Around注解的用法说明

    @Around注解可以用来在调用一个具体方法前和调用后来完成一些具体的任务. 比如我们想在执行controller中方法前打印出请求参数,并在方法执行结束后来打印出响应值,这个时候,我们就可以借助于@Around注解来实现: 再比如我们想在执行方法时动态修改参数值等 类似功能的注解还有@Before等等,用到了Spring AOP切面思想,Spring AOP常用于拦截器.事务.日志.权限验证等方面. 完整演示代码如下: 需要说明的是,在以下例子中,我们即可以只用@Around注解,并设置条件,

  • Spring AOP如何整合redis(注解方式)实现缓存统一管理详解

    前言 项目使用redis作为缓存数据,但面临着问题,比如,项目A,项目B都用到redis,而且用的redis都是一套集群,这样会带来一些问题. 问题:比如项目A的开发人员,要缓存一些热门数据,想到了redis,于是乎把数据放入到了redis,自定义一个缓存key:hot_data_key,数据格式是项目A自己的数据格式,项目B也遇到了同样的问题,也要缓存热门数据,也是hot_data_key,数据格式是项目B是自己的数据格式,由于用的都是同一套redis集群,这样key就是同一个key,有的数据

  • Spring AOP注解失效的坑及JDK动态代理

    @Transactional @Async等注解不起作用 之前很多人在使用Spring中的@Transactional, @Async等注解时,都多少碰到过注解不起作用的情况. 为什么会出现这些情况呢?因为这些注解的功能实际上都是Spring AOP实现的,而其实现原理是通过代理实现的. JDK动态代理 以一个简单的例子理解一下JDK动态代理的基本原理: //目标类接口 public interface JDKProxyTestService { void run(); } //目标类 publ

随机推荐