Spring Expressions, what does it mean value="{someName}" - spring

I am working with a Spring Boot Application that uses SpEl , it has some Redis annotations and it calls my attention the use of brackets on some expressions, i.e.:
#Cacheable(value = "{mycache}", key = "#param")
I can tell the SpEl expression when using # is to refer to the passed param, but for the first part "{myCache}" I am not sure what is the purpose of the braces.

Related

Spring Boot | spring EL using with annotation attribute value to set any random value using properties

I am using one existing spring boot annotation and want to set the attribute value dynamically using spring expression and want to have one constant value as a prefix,
sample Code snippet
#KafkaListener(topics="${topic.name}", groupId="#{'consumergroup' + (int)(java.lang.Math).random() }")
public void consumerMethod(){
}
I want to create a new consumer group for each new container using the above kind of implementation.
But I am facing the below exception.
Expression parsing failed; nested exception is
org.springframework.expression.spel.SpelParseException: EL1041E: After
parsing a valid expression, there is still more data in the
expression: 'lparen(()
kindly help me to either use template spring EL or any other way I can use to set dynamic consumer group id with the constant prefix.
groupId="#{'consumergroup' + (100 * T(Math).random()).intValue() }"
There is no cast operator in SpEL. Just because it uses a ConversionService internally to convert from one type to another. I use intValue() any way because the result of random() is Double (not double) - SpEL does coercion into type wrappers for API convenience.
The java.lang is imported into SpEL context automatically. No need to add it for Math type.
100 *. See Math.random() JavaDocs: it returns the value between 0.0 and 1.0. So, casting to int would always bring you only 0. The casting doesn't do rounding.
Also see Spring Boot configuration properties feature where you can use random value for the groupId:
spring.kafka.consumer.group-id=consumergroup${random.int}
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config.random-values

Using spring integration as a mediator

I try to use Spring integration as a simple mediator. We have a webapp residing on the intranet which can not be accessed from the outside. Now I want to expose this app through a mediator in the DMZ. This simply means that all url:s like http://gateway/TheApp/* should be forwarded to http://internal/TheApp/*. Really simple in theory but it seems that the component for handling outgoing http-reuests in Spring integration (HttpRequestExecutingMessageHandler) needs an explicut URI, i.e no wildcard matching. Can this be achieved with Spring integration?
The inbound gateway puts the url into a header; you can simply use an expression on the outbound gateway...
url-expression="headers['http_requestUrl'].replace('gateway', 'internal')"
If you are using Java #Configuration, you can use the constructor that takes an Expression...
Expression expression = new SpelExpressionParser().parseExpression(
"headers['http_requestUrl'].replace('gateway', 'internal')");
This test case does something similar by grabbing just the query string and appends it to a new URL.
In that case, it puts the query string in the payload; it could easily by added as a header instead (e.g. for a POST), using the <int:header/> child element.

Spring integration payload-expression: SPEL expression with args

I want to have a payload-expression in spring integration that does this:
#{T(java.util.Arrays).asList(#args[0],#args[1],#args[2])}
I can't get the args values to be taken as args. What's the proper what to do this?
Thanks
The #{...} syntax is for SpEL expressions evaluated once, while the context is initialized.
In this case, you simply need
payload-expression="T(java.util.Arrays).asList(#args[0],#args[1],#args[2])"

Calling static methods from Spring Security Expressions?

I'm looking for a way to extend Spring Security Expressions to support an existing security infrastructure. I'm aware you can extend the MethodSecurityExpressionRoot as described here, but I also found reference to directly calling static methods through Spring Expression Language (Spring EL or SpEL). Unfortunately the official page on Spring Expression methods doesn't directly describe how to do this.
How can I invoke a static method through Spring Expression methods?
By using the T(fully.qualified.name).methodName() syntax:
You can use the special T operator to specify an instance of java.lang.Class (the type). Static methods are invoked by using this operator as well. The StandardEvaluationContext uses a TypeLocator to find types, and the StandardTypeLocator (which can be replaced) is built with an understanding of the java.lang package. This means that T() references to types within java.lang do not need to be fully qualified, but all other type references must be.
The T element returns a reference to the type instead of an instance. For example, the equivalent of Collections.singleton("Hello") is
T(java.util.Collections).singleton('Hello')

Injecting Spring Spel Expressions into bean properties

How can I inject a String meant to be a spel expression into an app context bean property without having the context interpret the string property as a spel resolvable value.
<bean id="x" p:spelExpression="${#code}/${#value}"/>
I want the the class's setter property to take a string argument and creates a reusable SpelExpression as a private property of the bean, however, the spring application context appears to be recognizing the #variableName as spel expressions and attempting to interpret the expression at initialization time.
I find Spel interpretation to be very useful, but would like to to use spel internally as well, with expression injection into my own beans.
Is it possible to disable the Spel Interpretation of for a bean, or even for a whole context file (maybe with some namespace shenanigans) without having to disable or modify spel expression resolution for the whole application context.
The #{...} are markers for spel interpreter in xml context.
I don't undestand : ${#code}/${#value}. Good is #{code/value}, as I understand things, if code and value are id.
So, if you want a spel expression without interpret it, put string code/value in xml.

Resources