spel表达式注入 spel表达式解析

2025-02-08 05:58 - 立有生活网

SpringBoot中所有@Conditional注解和作用说明

上面例子,当下游服务返回502状态码时,gateway会重试3次。

1、@ConditionalOnClass,当classpath下发现该类的情况下进行自动配置。

spel表达式注入 spel表达式解析spel表达式注入 spel表达式解析


spel表达式注入 spel表达式解析


对于上面的例子,如果下游的返回带有头信息为 X-Response-Foo:1234 ,则会gateway会替换为 X-Response-Foo:Bar ,在返回给客户端。

2、@ConditionalOnMissingBean,当Spring Context中不存在该Bean时。

3、@ConditionalOnProperty(prefix = "example.show",value = "enabled",hingValue = "true"),当配置文件中example.show.enabled=true时。

5、@ConditionalOnExpression:基于SpEL表达式作为判断条件

var定义的可以在流程的任意状态访问.6、@ConditionalOnJa:基于JVM版本作为判断条件

7、ConditionalOnJndi:在JNDI存在的条件下查找指定的位置

8、@ConditionalOnMissingClass:当类路径下没有指定的类的条件下

9、@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下

10、@ConditionalOnResource:类路径下是否有指定的资源

11、@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定的Bean @ConditionalOnWebApplication:当前项目是Web项目的条件下

Spring中$与#的区别

自此运行时注入的全部内容已经全部介绍完啦。终于完了啦,下个月我们开始学习Spring的Aop机制,很期待吧,come接 上篇 on!

spring表达式语言简称 SPEL :是一个支持运行时查询和作对象图的强大的表达式语言。语法类似于 EL ,SpEL 使用 #{...} 作为定界符 , 所有在大括号中的字符都将被认为是 SpEL , SpEL 为 bean 的属性进行动态赋值提供了便利。

application.yml.

在spring中#{}号是支持spel表达式,$是字符串的拼接

Spring Web Flow

当然表达式也可以是方法,例如我在 User 类中添加如下两个方法:

Spring Web Flow :流程,基于Spring MVC 的DispatchServlet

也可以用 上面例子中,两种路由都会将响应的状态码设置为401。 指定一个路径,而不用 webflow:flow-location-pattern 和 base-path

FlowHandlerMapping 的工作仅仅是将请求重定向给 Spring Web Flow

响应请求的是 FlowHandlerAdapter 等同于Spring MVC的,处理请求.配置如下: cas-servlet.xml

如果流程是旅行,那么 状态 就是路途上的城镇,风景点, 转移 就是公路, 流程数据 就像一路买的纪念品和记忆

属性解释

id:在流程内标识这个状态,(逻辑视图名)

view:展现的逻辑视图名

model:表单所绑定的对象

属性解释:

evaluate:行为状态要做的事情

expression : 调用那个Action,并计算结果.用 SpEL 表达式

test 是SpEL表达式,返回结果必须是Boolean格式,可以调指定bean(一般是Action)中的一个方法.

Action中返回的写法

如果只有to属性,则是默认的转移状态

view:如果是 externalRedirect: 前缀,将重定向到流程的外部页面;如果是 flowRedirect: 前缀,将重定向到另一个流程中异常转移

全局转移 将重复写的共用的转移抽取出来

作用域

开始状态:默认是个流程定义文件中的个状态,也可以用 start-state

-### 实例

-### 保护Web流程

找到的类似文章链接

spring cloud gateway系列教程2——GatewayFilter_下篇

在投票器中,我们可以看到专门处理 @PreAuthorize 注解的类 PreInvocationAuthorizationAVoter,我们来看下他里边的核心方法:

RequestRateLimiter GatewayFilter Factory使用 RateLimiter 来决定当前请求是否允许通过,如果不允许,则默认返回状态码 HTTP 429 - Too Many Requests 。

权限的实现方式千千万,又有各种不同的权限模型,然而归结到代码上,无非两种:

RequestRateLimiter GatewayFilter可以使用一个可选参数 keyResolver 来做速率限制。

keyResolver 是 KeyResolver 接口的一个实现bean,在配置里面,通过SpEL表达式 #{@myKeyResolver} 来管理bean的名字 myKeyResolver 。

KeyResolver.ja.

KeyResolver 接口允许你使用不同的与之类似,采用XML的方式也是硬编码:策略来得出限制请求的key,未来,也会推出一些 KeyResolver 的不同实现。

KeyResolver 默认实现是 PrincipalNameKeyResolver ,通过 WebExchange 中获取 Principal ,并以 Principal.getName() 作为限流的key。

如果 KeyResolver 拿不到key,请求默认都会被限制,你也可以自己配置 spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key :是否允许空key, spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code :空key时返回的状态码。

application.properties.

基于 Stripe 的redis实现方案,依赖 spring-boot-starter-data-redis-reactive Spring Boot starter,使用的是令牌桶算法。

redis-rate-limiter.replenishRate 配置的是每秒允许通过的请求数,其实就是令牌桶的填充速率。

redis-rate-limiter.burstCapacity 配置的是一秒内的请求数,其实就是令牌桶的容量,如果设置为0,则会阻塞所有请求。

所以可以通过设置相同的 replenishRate 和 burstCapacity 来实现匀速的速率控制,通过设置 burstCapacity 大于 replenishRate 来允许系统流量瞬间突发,但是对于这种情况,突发周期为 burstCapacity / replenishRate 秒,如果周期内有两次请求突发的情况,则第二次会有部分请求丢失,返回 HTTP 429 - Too Many Requests 。

Config.ja.

上面定义了每个用户每秒10个请求的速率限制,允许20的突发流量,突发完,下一秒只允许10个请求通过了, KeyResolver 定义了通过请求获取请求参数 user 作为key。

你也可以实现 RateLimiter 接口自定义自己的请求速率限制器,在配置文件中使用SpEL表达式配置对应的bean的名字即可。

上面路由会执行302重定向到 。

RemoveNonProxyHeaders GatewayFilter Factory转发请求是会根据 IETF 的定义,默认会移除下列的头信息:

你也可以通过配置 spring.cloud.gateway.filter.remove-non-proxy-headers.headers 来更改需要移除的header列表。

RemoveRequestHeader GatewayFilter Factory配置header的name,即可以移除请求的header。

上面路由在发送请求给下游时,会将请求中的 X-Request-Foo 头信息去掉。

RemoveResponseHeader GatewayFilter Factory通过配置header的name,会在响应返回时移除header。

上面路由会在响应返回给gateway的客户端时,将 X-Response-Foo 响应头信息去掉。

RewritePath GatewayFilter Factory使用路径 regexp 和替换路径 replacement 两个参数做路径重写,两个都可以灵活地使用ja的正则表达式。

对于上面的例子,如果请求的路径是 /foo/bar ,则gateway会将请求路径改为 /bar 发送给下游。

RewriteResponseHeader GatewayFilter Factory的作用是修改响应返回的header内容,需要配置响应返回的header的 name ,匹配规则 regexp 和替换词 replacement ,也是支持ja的正则表达式。

举个例子,对于上面的filter,如果响应的header X-Response-Foo 的内容是 /42?user=ford&password=omg!what&flag=true ,这个内容会修改为 /42?user=ford&password=&flag=true 。

SeSession GatewayFilter Factory会在请求下游时强制执行 WebSession::se 方法,用在那种像 Spring Session 延迟数据存储的,并在请求转发前确保session状态保存情况。

如果你将 Spring Secutiry 于 Spring Session 集成使用,并想确保安全信息都传到下游机器,你就需要配置这个filter。

SecureHeaders GatewayFilter Factory会添加在返回响应中一系列安全作用的header,至于为什么,英文好的可以看一下 这篇博客 。

默认会添加这些头信息和默认内容:

如果你想修改这些头信息的默认内容,可以在配置文件中添加下面的配置:

前缀: spring.cloud.gateway.filter.secure-headers

上面的header对应的后缀:

前后缀接起来即可,如: spring.cloud.gateway.filter.secure-headers.xss-protection-header

SetPath GatewayFilter Factory采用路径 template 参数,通过请求路径的片段的模板化,来达到作修改路径的母的,运行多个路径片段模板化。

对于上面的例子,如果路径是 /foo/bar ,则对于下游的请求路径会修改为 /bar 。

SetResponseHeader GatewayFilter Factory通过设置 name 和 value 来替换响应对于的header。

SetStatus GatewayFilter Factory通过配置有效的Spring HttpStatus 枚举参数,可以是类似于404的这些数字,也可以是枚举的name字符串,来修改响应的返回码。

StripPrefix GatewayFilter Factory通过配置 parts 来表示截断路径前缀的数量。

如上面例子中,如果请求的路径为 /name/bar/foo ,则路径会修改为 /foo ,即将路径的两个前缀去掉了。

Retry GatewayFilter Factory可以配置针对不同的响应做请求重试,可以配置如下参数:

RequestSize GatewayFilter Factory会限制客户端请求包的大小,通过参数 RequestSize 来配置上传大小,单位字节。

如果请求大小超过5000kb限制,则会返回状态码 413 Payload Too Large 。

Modify Request Body GatewayFilter Factory可以修改请求体内容,这个只能通过ja来配置。

Modify Response Body GatewayFilter Factory用于修改响应返回的内容,同样只能通过ja配置。

这一章接着上一章介绍了Spring Cloud Gateway的Gateway Filter使用场景,下一章讲 Global Filters的使用 。

如果想查看其他spring cloud gateway的案例和使用,可以点击 查看

Spring高级配置之运行时注入

我们就可以通过表达式调用这两个方法,如下:

之前,我们设置Bean的属性值时,采用的都是硬编码的形式。比如,在定义BlankDisc时:

如果SpEL表达式访问类作用域的方法或常量时,要使用到T()这个关键的运算符: #{T(ja.lang.Math)} 运算符的结果是一个Class对象,它代表了ja.lang.Math。通过它我们可以访问Math的静态方法和常量。

硬编码的坏处想必大家都知道,所以我们就想能不能让这些值在程SpEL能够通过ID引入其他的bean、bean的属性和bean的方法:序运行时再确定。其实Spring已经提供了两种方式实现运行时注入的功能:

Environment的getProperty()方法有四个重载方法:

前两种形式的getProperty()方法都是返回String类型的值。后两种重载方法不是直接返回字符串,而是将获取到的值转化为指定类型的值,比如获取连接池中维持连接的总数量:

在使用getProperty()获取属性时,如果这个属性没有定义,那他获取的是null,如果我们不想让这样的情况发生,可以使用getRequiredProperty()方法:

如果disc.title或disc.arist没有定义的话,将会抛出IllegalStateException异常。

如果你想检查某个属性是否存在,那么可以调用containsProperty()方法:

如果你想将属性解析为类的话,可以使用getPropertyAsClass()方法:

除了属性相关的功能外,Environment还提供了一些方法来检查哪些profile处于激活状态:

在Spring装配中,占位符的形式为“${...}”包装的属性名称。下面我们使用属性占位符在XML中解析tomcat连接池bean的属性:

要使用占位符,需要配置PropertySourcesPlaceholderConfigurer bean:

在Xml配置要使用到命名空间中的元素,它可以为我们生成PropertySourcesPlaceholderConfigurer bean:

Spring 3引入了Spring表达式(Spring Excpression Language,SpEL),他能够以一种强大和简洁的方式将值装配到bean属性和构造器参数中,这个过程中所使用的表达式会在运行时计算得到值。SpEL的特性有以下几点:

上面几个只是几个基本的SpEl样例,后面我们会着重介绍,下面我们先看看使用SpEL表达式装配bean的属性:

上例中使用到@Value注解,在注解中设置SpEL表达式。上面我们学习了几个简单的样例,也学习了如何将SpEL表达式解析得到的值注入到bean中,那么我们来继续学习一下SpEl表达式支持的基础表达式吧。

使用SpEL字面量样式可以表示整数、浮点数、String以及Boolean类型的值:

如果还可以对方法的返回值做处理,直接调用返回值类型的属性或方法,设sayHello()返回值是String类型: #{blankDisc.sayHello().toUpperCase()} ,这样就可以获取返回值的大写字母形式。

但如果返回值是null,调用它的方法就会报空指针异常,为了预防这种情况,可以使用 ? 判断获得返回值是否为null: #{blankDisc.sayHello()?.toUpperCase()} 如果sayHello()方法返回值是null,SpEl将不会调用toUpperCase()方法,SpEL的返回值是null。

SpEL提供了多个运算符,这些运算符可以使用到SpEL表达式上:

SpEL通过matches运算符支持表达式中的模式匹配,匹配成功返回true,否则否则返回false,下面我们判断邮箱是否符合正则表达式:

使用SpEL引用列表中的一个元素: #{jubox.songs[4].title} ,获取列表的第5个元素(基于0开始),[] 是从或数组中按照索引取元素。

SpEL提供了查询运算符(.?[]),他会用来对进行过滤,得到的一个子集。下面我们将Aeroith的歌曲过滤出来:

.^[]查询个匹配项

.$[]查询一个匹配项

投影运算符(.![]),将对象特定的字段投影到另一个中,下面我们将歌曲的名称投影到另一个String类型的中:

我们还可以过滤要投影的歌曲,下面我们获取Aeroith歌曲的title:

Spring Security 中的权限注解很神奇吗?

4、@ConditionalOnBean:当容器中有指定的Bean的条件下

最近有个小伙伴在微信群里问 Spring Security 权限注解的问题:

很多时候事情就是这么巧,松哥最近在做的 tienchin 也是基于注解来处理权限问题的,所以既然大家有这个问题,咱们就一块来聊聊这个话题。

先来看看 Spring Security 权限注解的具体用法,如下:

类似于上面这样,意思就是说,当前用户需要具备 tienchin:channel:query 权限,才能执行当前的接口方法。

那么要搞明白 @PreAuthorize 注解的原理,我觉得得从两个方面入手:

我们一个一个来看。

Spring Expression Language(简称 SpEL)是一个支持查询和作运行时对象导航图功能的强大的表达式语言。它的语法类似于传统 EL,但提供额外的功能,最出色的就是函数调用和简单字符串的模板函数。

SpEL 给 Spring 社区提供一种简单而高效的表达式语言,一种可贯穿整个 Spring 产品组的语言。这种语言的特性基于 Spring 产品的需求而设计,这是它出现的一大特色。

在我们离不开 Spring 框架的同时,其实我们也已经离不开 SpEL 了,因为它太好用、太强大了,SpEL 在整个 Spring 家族中也处于一个非常重要的位置。但是很多时候,我们对它的只了解一个大概,其实如果你系统的学习过 SpEL,那么上面 Spring Security 那个注解其实很好理解。

我先通过一个简单的例子来和大家捋一捋 SpEL。

为了省事,我就创建一个 Spring Boot 工程来和大家演示,创建的时候不用加任何额外的依赖,就最最基础的依赖即可。

代码如下:

expressionStr 是我们自定义的一个表达式字符串,这个字符串通过一个 ExpressionParser 对象将之解析为一个 Expression,接下来就可以执行这个 exp 了。

执行的时候有两种方式,对于我们上面这种不带任何额外变量的,我们可以直接执行,直接执行的方式如下:

这个打印结果为 3。

我记得之前有个小伙伴在群里问想执行一个字符串表达式,但是不知道怎么办,js 中有 eval 函数很方便,我们 Ja 中也有 SpEL,一样也很方便。

不过很多时候,我们要执行的表达式可能比较复杂,这时候上面这种调用方式就不太够用了。

此时我们可以为要调用的表达式设置一个上下文环境,这个时候就会用到 EvaluationContext 或者它的子类,如下:

当然上面这个表达式不需要设置上下文环境,我举一个需要设置上下文环境的例子。

例如我现在有一个 User 类,如下:

现在我的表达式是这样:

这个表达式就表示获取 user 对象的 username 属性。将来创建一个 user 对象,放到 StandardEvaluationContext 中,并基于此对象执行表达式,就可以打印出来想要的结果。

如果我们将 user 对象设置为 rootObject,那么表达式中就不需要 user 了,如下:

表达式就一个 username 字符串,将来执行的时候,会自动从 user 中找到 username 的值并返回。

调用有参的 sayHello:

就直接写方法名然后执行就行了。

调用无参的 sayHello:

这些就都好RedirectTo GatewayFilter Factory使用 status 和 两个参数,其中 status 必须是300系列的HTTP状态码, 则是跳转的地址,会放在响应的 Location 的header中(协议中转跳的header)。懂了。

甚至,我们的表达式也可以涉及到 Spring 中的一个 Bean,例如我们向 Spring 中注册如下 Bean:

然后通过 SpEL 表达式来调用这个名为 us 的 bean 中的 sayHello 方法,如下:

给配置的上下文环境设置一个 bean 解析器,这个 bean 解析器会自动跟进名字从 Spring 容器中找打响应的 bean 并执行对应的方法。

当然,关于 SpEL 的还有很多,我就不一一列举了。这里主要是想让小伙伴们知道,有这么个技术,方便大家理解 @PreAuthorize 注解的原理。

接下来我们就回到 Spring Security 中来看 @PreAuthorize 注解。

松哥之前的 vhr 使用的是前者。

@PreAuthorize 注解当然对应的是后者。这次做的 tienchin 项目就是后者,我们来看一个例子:

注解好说,里边的 @ss.hasPermi('tienchin:channel:query') 是啥意思呢?

这个 hasPermi 方法的逻辑其实很简单:

这个判断逻辑很简单,就是现在,当你看到这个 before 方法的时候,应该会觉得比较熟悉了吧。获取到当前登录的用户,判断当前登录用户的权限中是否具备当前请求所需要的权限。具体的判断逻辑没啥好说的,就是看中是否存在某个字符串。

那么这个方法是在哪里调用的呢?

大家知道,Spring Security 中处理权限的过滤器是 FilterSecurityInterceptor,所有的权限处理最终都会来到这个过滤器中。在这个过滤器中,将会用到各种投票器、表决器之类的工具,这里我就不细说了,之前的 Spring Security 系列教程都有详细介绍。

框架的源码写的就是好,你一看名字就知道他想干嘛了!这里就进入到一句,调用了一个 A 中到前置通知,来判断权限是否满足:

就这样,是不是很简单?

好啦,今天就和小伙伴们分享这么多,在松哥近期推出的 tienchin 项目视频中,也会通过视频的形式跟大家细聊这个知识点。

温暖的瞬间满分作文800字 温暖的瞬间初中作文

温暖的瞬间作文800字(2或3个小标题) 记忆中,父亲的眼神里总是充满严肃,如古洞深巷般悠远。很少与父亲碰面,时间是那般抵触,将我和父亲错开。于是,我为寻找一份相聚,注意每一个瞬间,珍···

28001职业健康安全管理体系 职业健康安全管理

如何取得GB/T28001:2001职业健康安全管理体系认证证书 GB/T28001:2001职业健康安全管理体系认证的基本概念与用途我想您已基本了解,我就说说取证的基本流程吧。 28001职业健康安全管理体系 职业健康···

自由落体空气阻力计算公式_自由落体空气阻力

空气阻力公式 公式是什么 空气阻力,指空气对运动物体的阻碍力,是运动物体受到空气的弹力而产生的。下面是我整理的空气阻力公式相关内容,来看一下吧! 自由落体空气阻力计算公式_自由落···