Springing Java Apps: Servlet and Reactive Ways

child, dandelion, kids-1347385.jpg

Spring Origins

Spring is open source and has large community support due to its widespread acceptance. The first version was written by Rod Johnson and was released with an Apache license in 2003. Spring Source was the company founded by founders, which later got purchased by VMWare in 2008. As per Wikipedia, In April 2013, VMware, and its parent company EMC Corporation, formally created a joint venture (with GE) called Pivotal Software. All of VMware’s application-oriented products, including Spring were transferred to this organization. In 2019, Pivotel was merged into VMWare, and currently, the team managing spring works for VMWare. https://spring.io/team

What is Spring

The Spring Framework is divided into modules. Applications can choose which modules they need. At the heart are the modules of the core container, including a configuration model and a dependency injection mechanism. Beyond that, the Spring Framework provides foundational support for different application architectures, including messaging, transactional data and persistence, and web. It also includes the Servlet-based Spring MVC web framework and, in parallel, the Spring WebFlux reactive web framework which can run on non-Servlet Containers. Most of the earlier framework code was in fact enhancements on JAVA EE specifications like

The tale of two restaurants

There are two approaches now to load a Java APP in Production

  • Servlet : Spring WebMVC
  • Reactive : Spring WebFlex

The thread-per-request model provided by Servlet helps us to serve many requests by having a Servlet Container like Tomcat keep a pool of connections, and the new requests are provided a connection from the pool, however, an increase in the number of requests need a Horizontal scaling of servers. Generally, a Server-side load balancer with Autoscaling would be enough for most practical purposes.

The concurrency model provided by Reactive Stack helps us handle increasingly more requests with a relatively less number of threads and hence lesser horizontal scaling. This concurrency is achieved via different models and one of the more famous models is the event loop model. This model is the same that node js applications use to serve the requests with better response time results.

An easier analogy to understand both models is to imagine a scenario where Restaurant1 has x servers and y customers. Suppose each customer is assigned a server, correspondingly The thread per request model is able to handle scenarios where the number of servers is equal to customers. However, the server is free a lot of times like when food is prepared, or when the food is being consumed, hence we see that thread that is assigned to request is blocked until it gets completed.
Consider the scenario in Restaurant2, where the server is not assigned to any customer but works round clock serving all the customers in an event loop. The lazy servers(threads) are being completely utilized, however, this is easy said than done because many times creating a completely non-blocking API is difficult, the reactive program is a step in that direction, and projects like Reactive Mongo, WebClient, WebSocket, and Webflux with Nitty server are aides in achieving the concurrency.

Servlet Way

Servlet Origins

James Gosling and his team are the original creators of Java when they worked in Sun-Microsystems around 1995. Now during that time, Gosling had the idea of this language to be useful in Web servers as well, Pavani Diwanji a Fresh Stanford Graduate at that time in Gosling’s team worked on this, created the first Java Servlet V1 specification in 1997. 

What are Servlets ?

As per Oracle docs, a servlet is a Java programming language class used to extend the capabilities of servers that host applications accessed by means of a request-response programming model. I would agree the definition is not a good one, we can consider a class as servlets if it implements the Servlet interface, i.e which defines lifecycle methods. We can implement the GenericServlet or HttpServlet depending on the need, the later when has the doGet & doPost methods that we need in a web app.

Apache Tomcat

Apache HTTP Server is a free and open-source cross-platform web server software, released under the terms of Apache License 2.0. Apache is developed and maintained by an open community of developers under the auspices of the Apache Software Foundation.  Apache served 24.63% of the million busiest websites.

  • Few of the features supported by Server are
    • Loadable Dynamic Modules
    • Multiple Request Processing modes (MPMs) including Event-based/Async, Threaded and Prefork.
    • Highly scalable (easily handles more than 10,000 simultaneous connections)
    • Handling of static files, index files, auto-indexing and content negotiation
    • Virtual Hosting

Tomcat: is the Web container that Manages the execution of servlets. The lifecycle of a servlet is controlled by the container in which the servlet has been deployed. A web container will typically create a thread to handle each request.  When a request is mapped to a servlet, the container performs the following steps.

  • If an instance of the servlet does not exist, the web container:
    1. Loads the servlet class
    2. Creates an instance of the servlet class
    3. Initializes the servlet instance by calling the init method (initialization is covered in Creating and Initializing a Servlet)
    4. The container invokes the service method, passing request and response objects.

Now Let us take a deep dive into How requests are served in the Spring Web MVC application

Spring Web MVC

Spring’s web MVC framework is, like many other web MVC frameworks, request-driven, designed around a central servlet that dispatches requests to controllers and offers other functionality that facilitates the development of web applications. The request processing workflow of the Spring Web MVC DispatcherServlet is illustrated in the above diagram.

Dispatcher Servlet Creation

Spring MVC, like many other web frameworks, is designed around the front controller pattern where a central Servlet, the DispatcherServlet, provides a shared algorithm for request processing. The DispatcherServlet needs to be declared and mapped according to the Servlet specification by using Java configuration or in web.xml. The following example shows Java and web.xml configuration to register and initialize DispatcherServlet:

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) {

        // Load Spring web application configuration
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(AppConfig.class);

        // Create and register the DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(context);
        ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/app/*");
    }
}
<web-app>
    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>
</web-app>

In the Web MVC framework, each DispatcherServlet has its own WebApplicationContext, which inherits all the beans already defined in the root WebApplicationContext. These inherited beans defined can be overridden in the servlet-specific scope, and you can define new scope-specific beans local to a given servlet instance.

WebApplicationContext hierarchy

Request Processing

In the preceding example, all requests from /app will be handled by the app DispatcherServlet. This is only the first step in setting up Spring Web MVC. We will need to configure the various beans used by the Spring Web MVC framework, henceforth, If we follow the XML based approach, then upon initialization of a DispatcherServlet, the framework looks for a file named [servlet-name]-servlet.xml in the WEB-INF directory of your web application and create the beans defined there. These special beans process requests and renders the appropriate views. You can configure them in the WebApplicationContext, just as you configure any other bean. These beans are described in the following table

HandlerMapping: Map a request to a handler along with a list of interceptors for pre-and post-processing. The mapping is based on some criteria, the details of which vary by HandlerMapping implementation. The two main HandlerMapping implementations are RequestMappingHandlerMapping (which supports @RequestMapping annotated methods) and SimpleUrlHandlerMapping (which maintains explicit registrations of URI path patterns to handlers).

HandlerAdapter: Help the DispatcherServlet to invoke a handler mapped to a request, regardless of how the handler is actually invoked. For example, invoking an annotated controller requires resolving annotations. The main purpose of a HandlerAdapter is to shield the DispatcherServlet from such details.

Web MVC Config: Applications can declare the infrastructure beans listed in Special Bean Types that are required to process requests. The DispatcherServlet checks the WebApplicationContext for each special bean.

Thread Per Request Model

The container instantiates one instance of your Spring MVC DispatcherServlet when your application loads for the first time, this is defined by the load on the startup property in the configuration. Apache web server is waiting for client HTTP requests, When a request arrives, it needs to check and see if a certain request belongs to a servlet, if so it lets the Servlet take the request forward and passes Servlet management to the Tomcat container for the rest of flow.

The container manages a pool of Threads(default 200) which it uses to respond to connections, ie. HTTP requests. When such a request arrives, the container picks a Thread from the pool and, within that Thread, executes the service() method on the DispatcherServlet which dispatches to the correct @Controller based on Handler mapping and other special beans in the DispatcherServlet from the configuration defined in [servlet-name]-servlet.xml or Java configuration.

Reactive Way

work-in-progress, sign, activity-24027.jpg

References

error: Content is protected !!
Scroll to Top