How Long Will It Take before Java Developers Can Utilize Serverless?

By Fang Jian (luoye), Founder and Head of the Spring Cloud Alibaba Open-Source Project

This article is taken from the book, In-depth Understanding and Practices of Spring Cloud, written by Fang Jian. This article describes how to deal with FaaS scenarios under the Java microservice framework Spring Boot/Cloud.

Serverless and FaaS

In 2019, O’Reilly researched 1,500 IT professionals. The result showed that 40% of the respondents work in organizations that adopt the Serverless architecture. The DataDog Survey from 2020 shows that more than 50% of AWS users are using AWS Lambda based on Serverless architecture.

Serverless is becoming a mainstream trend. The following figure shows the change from the management of monolithic applications to microservice applications to functions.

So far, Serverless does not have a precise definition. Martin Fowler wrote an article on his blog called Serverless Architectures, which defines Serverless as the combination of BaaS and FaaS.

BaaS is short for Backend as a Service, and FaaS is short for Function as a Service.

Now, let’s talk about FaaS. This is the definition of FaaS from Wikipedia, “Function as a Service (FaaS) is a type of cloud computing service. It provides a platform that allows customers to develop, run, and manage application functions without building and maintaining the infrastructure typically associated with application development and launch. Building applications based on this model is a way to implement Serverless architecture. FaaS is usually used when building microservice applications.”

Python and JavaScript are natively supported in Lambda and can be combined perfectly with FaaS. The Serverless Framework Research Report also supports this combination. Node.js and Python are the top two languages used in FaaS.

Java-based applications start up slowly because JVM consumes a lot of memory. So, FaaS is not suitable for Java-based applications. This is why Java usage in FaaS is low.

Spring Boot/Cloud has become the de facto standard for Java developers. Dependency injection is the core of the Spring Framework. What will happen if Spring Boot/Cloud is used to address FaaS scenarios? This involves the Spring Cloud Function being introduced in this article.

Java Function

Before introducing the Spring Cloud Function, let’s take a look at definitions of core functions in Java.

JDK 1.8 released a new feature called Lambda expressions. Many functions are provided in the java.util.function package. The following three functions are particularly important:

public interface Function<T, R> {
R apply(T t);

For example, the map method in Stream API can change an uppercase string to a lowercase one through the Function:

Stream.of("a", "b", "c").map(String::toUpperCase);

The map method requires a Function parameter:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);
public interface Consumer<T> {
void accept(T t);

For example, the forEach method of Stream API can traverse each element and perform corresponding business logic processing:

RestTemplate restTemplate = new RestTemplate();
Stream.of("200", "201", "202").forEach(code -> {
ResponseEntity<String> responseEntity =
restTemplate.getForEntity("" + code, String.class);
public interface Supplier<T> {
T get();

For example, the custom Supplier can return a random number:

Random random = new Random();Supplier supplier100 = () -> random.nextInt(100);
Supplier supplier1000 = () -> random.nextInt(1000);

Spring Cloud Function

The programming model of the Java Function is very simple, which is essentially the three core functions:

  • Supplier
  • Function
  • Consumer

The Spring Cloud Function is a Spring ecosystem project related to Serverless (FaaS). It is designed to enhance the Java Function in the following aspects:

  • Unified FaaS Programming Model of Cloud Vendors: The slogan of Spring Cloud Function is “Write Once, Run Anywhere.” The Spring Cloud Function code can run locally and in various products of cloud vendors, such as AWS Lambda, GCP Cloud Functions, and Azure Functions.
  • Automatic Type Conversion: For those that learned about Spring MVC or Spring Cloud Stream, the HttpMessageConverter or MessageConverter is very familiar. This converter automatically converts the HTTP BODY (or Message Payload), HTTP Query Parameter, and HTTP HEADER (or Message HEADER) to the corresponding POJO. With this feature, no attention is needed to the input parameters and returned values of the function. The original input parameter information can be obtained through String parameters. Moreover, with the POJO parameter called User, the original input parameters can be automatically converted into User objects.
  • Function Combination: Multiple functions can be combined.
  • Function Management: FunctionCatalog and FunctionRegistry interfaces are provided for Function management. They allow Function management in ApplicationContext and dynamic Function Registration.
  • Reactive Support: The Spring Cloud Function provides Reactive functions, such as FluxFunction, FluxSupplier, and FunctionConsumer.

The Spring Cloud Function automatically and deeply integrates with the original components in the Spring ecosystem:

  • Spring Web/Spring WebFlux: An HTTP request is a function call.
  • Spring Cloud Task: One-time Task execution is a one-time function call.
  • Spring Cloud Stream: One-time message consumption/production/conversion is a one-time function call.

The unified FaaS programming model of cloud vendors is explained below to give a better understanding of the Spring Cloud Function.

AWS Lambda was the first cloud vendor to provide the FaaS service. RequestStreamHandler is the interface provided by AWS for Java developers. Use the code below to implement the following interface:

public class HandlerStream implements RequestStreamHandler {
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException

Azure Functions provides the @HttpTrigger annotation for Java developers:

public class Function {
public String echo(@HttpTrigger(name = "req",
methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS)
String req, ExecutionContext context) {

As shown above, different codes have to be written for different cloud vendors. This process is very difficult if users want to change the cloud vendor.

Interfaces or annotations provided by AWS, Azure, or GCP have no initialization logic related to the Spring context. If a Spring Boot/Cloud application is migrated to the FaaS platform, modifications like the Spring context initialization logic are required. Spring Cloud Function was created to solve these problems.

Spring Cloud Function Usage

The Spring Cloud Function and Spring Web:

public class SpringCloudFunctionWebApplication {
public static void main(String[] args) {, args);
public Function<String, String> upperCase() {
return s -> s.toUpperCase();
public Function<User, String> user() {
return user -> user.toString();

Access the corresponding Endpoint:

$ curl -XPOST -H "Content-Type: text/plain" localhost:8080/upperCase -d hello
$ curl -XPOST -H "Content-Type: text/plain" localhost:8080/user -d '{"name":"hello SCF"}'
User{name\u003d\u0027hello SCF\u0027}

The Spring Cloud Function and Spring Cloud Stream:

public class SpringCloudFunctionStreamApplication {
public static void main(String[] args) {, args);
public Function<String, String> uppercase() {
return x -> x.toUpperCase();
public Function<String, String> prefix() {
return x -> "prefix-" + x;

Add the function-related configurations. For each message in an input-topic, the payload is converted into uppercase type and mounted with a prefix of prefix-. Then, the payload is written to the output-topic. For example:|prefix

Spring Cloud Function and Spring Cloud Task:

public class SpringCloudFunctionTaskApplication {
public static void main(String[] args) {, args);
public Supplier<List<String>> supplier() {
return () -> Arrays.asList("200", "201", "202");
public Function<List<String>, List<String>> function() {
return (list) -> item -> "prefix-" + item).collect(Collectors.toList());
public Consumer<List<String>> consumer() {
return (list) -> {;

Add function-related configurations. The Supplier simulates the job input source. The Function simulates the processing of the job input source, and the Consumer simulates the processing of data processed by the Function. For example:

About the Author

Fang Jian is the Founder and Head of the Spring Cloud Alibaba open-source project. Fang is the author of In-depth Understanding and Practices of Spring Cloud. He is also an Apache RocketMQ Committer and Alibaba Nacos Committer. He has written series of articles, like SpringMVC Source Code Analysis and SpringBoot Source Code Analysis on his blog. Currently, Fang is focusing on microservices, cloud-native, and Kubernetes.

Original Source:

Follow me to keep abreast with the latest technology news, industry insights, and developer trends.