[[expressions-ref-functions]]
= Functions

You can extend SpEL by registering user-defined functions that can be called within the
expression string. The function is registered through the `EvaluationContext`. The
following example shows how to register a user-defined function:

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
	Method method = ...;

	EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
	context.setVariable("myFunction", method);
----

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
	val method: Method = ...

	val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
	context.setVariable("myFunction", method)
----
======

For example, consider the following utility method that reverses a string:

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
	public abstract class StringUtils {

		public static String reverseString(String input) {
			StringBuilder backwards = new StringBuilder(input.length());
			for (int i = 0; i < input.length(); i++) {
				backwards.append(input.charAt(input.length() - 1 - i));
			}
			return backwards.toString();
		}
	}
----

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
	fun reverseString(input: String): String {
		val backwards = StringBuilder(input.length)
		for (i in 0 until input.length) {
			backwards.append(input[input.length - 1 - i])
		}
		return backwards.toString()
	}
----
======

You can then register and use the preceding method, as the following example shows:

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
	ExpressionParser parser = new SpelExpressionParser();

	EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
	context.setVariable("reverseString",
			StringUtils.class.getDeclaredMethod("reverseString", String.class));

	String helloWorldReversed = parser.parseExpression(
			"#reverseString('hello')").getValue(context, String.class);
----

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
	val parser = SpelExpressionParser()

	val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
	context.setVariable("reverseString", ::reverseString::javaMethod)

	val helloWorldReversed = parser.parseExpression(
			"#reverseString('hello')").getValue(context, String::class.java)
----
======



