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')
Related
Due to the Spring Expression Language Reference it's possible to register user-defined funtions which can be used in expressions.
How can I register such a function in the context of Spring AMQP in order to determine a queue name?
It is not fully clear in what context you'd like to determine that queue, but I believe the answer for you is still going to be that it is not possible to customize an internal EvaluationContext used in the framework for SpEL parts of configuration. As a workaround you can use a T operator for your static methods to call. Essentially those SpEL-functions are wrappers around static methods.
For Spring Framework where is the complete list of reserved words or Predefined Variables about SpEL with their respective explanation? It such as for:
environment
systemProperties
systemEnvironment
For example in this valuable tutorial is just shown the 2 latest of the list shown above
Spring Expression Language (SpEL) Predefined Variables
Consider if Spring 6 added more of them, it as an improvement, therefore could be more.
Yes, I did do a research - currently for version 6 - at the official documentation at:
Spring Expression Language (SpEL)
But does not contain the reserved words.
There isn't really a list of reserved words for SpEL like what you are looking for, at least not in generic SpEL parsing and evaluation.
There is default SpEL support in the application context and notably in #Value annotations, as documented in the reference guide: Expressions in Bean Definitions.
Thi is provided via a SpEL StandardEvaluationContext which uses the beanFactory as the root object. Or rather, it uses a BeanExpressionContext view of the bean factory plus a dedicated PropertyAccessor is added to this evaluation context so that every beanName in the bean factory is considered a property of that root object during evaluation.
As a result, if a bean named foo is registered in the factory, #Value("#{ foo }") will be interpreted as "the property foo of the root object", which resolves to the aforementioned bean.
So systemProperties/systemEnvironment and environment are not really predefined SpEL variables, but rather standard beans in an AbstractApplicationContext.
I'm learning how to use Mapstruct in a Spring Boot and Kotlin project.
I've got a generated DTO (ThessaurusDTO) that has a List and I need this mapped into a List on my model (Vocab).
It makes sense that MapStruct can't map this automatically, but I know for a fact that the first list will always be size = 1. I have no control on the API the DTO model belongs to.
I found on the documentation that I can create define a default method implementation within the interface, which would loosely translate to a normal function in Kotlin
My mapper interface:
#Mapper
interface VocabMapper {
#Mappings(
// ...
)
fun thessaurusToVocab(thessaurusDTO: ThessaurusDTO): Vocab
fun metaSyns(nestedList: List<List<String>>): List<String>
= nestedList.flatten()
}
When I try to do a build I get the following error:
VocabMapper.java:16: error: Can't map collection element "java.util.List<java.lang.String>" to "java.lang.String ". Consider to declare/implement a mapping method: "java.lang.String map(java.util.List<java.lang.String> value)".
It looks like mapStruct is still trying to automatically do the mapping while ignoring my custom implementation. Am I missing something trivial here?
I found on the documentation that I can create define a default method implementation within the interface, which would loosely translate to a normal function in Kotlin
From my understand of what I found online, Kotlin does not properly translate an interface function into a default method in Java, but actually generates a class that implements the interface.
If that's the problem, you can annotate metaSyns with #JvmDefault:
Specifies that a JVM default method should be generated for non-abstract Kotlin interface member.
Usages of this annotation require an explicit compilation argument to be specified: either -Xjvm-default=enable or -Xjvm-default=compatibility.
See the link for the difference, but you probably need -Xjvm-default=enable.
I've seen to have fixed this by relying on an abstract based implementation, instead of using an interface.
From my understand of what I found online, Kotlin does not properly translate an interface function into a default method in Java, but actually generates a class that implements the interface.
https://github.com/mapstruct/mapstruct/issues/1577
I don't think spring does use clone in making a proto, it will be cheating if they use reflection API and create a copy object and call it a clone/proto, Springs proto never satisfies any condition of prototype pattern.
Yes, you are right. The #Scope("prototype") annotation in Spring doesn't implement the prototype design pattern by the GoF. While the prototype design pattern creates new objects by cloning a given prototype (see here), Spring's #Scope("prototype") will not do that. It will create a new object every time by Spring's default object creation mechanism (which is reflection I guess). If you look at Spring's documentation, it evens says that #Scope("prototype") is a replacement for Java's new operator:
In some respects, the Spring container’s role in regard to a
prototype-scoped bean is a replacement for the Java new operator.
(See here)
I found that, by default when I using Spring MVC, "2010/01/02" binds correctly, but "2010-01-02" does not.
I know Spring has some useful binding mechanisms like initBinder. However, in this question I want to know where is the rule defined. Does anyone know that for example RFC documents of HTTP or Spring references.
It's just coincidence.
Spring MVC can implicitly convert input parameters to model objects via their single-argument constructor that takes String (if model objects have such constructors). Date has this constructor, though it's deprecated, so that this behaviour is determined by behaviour of that constructor.