Spring Boot Interview Questions

Browse our top Spring Boot interview questions and answers and start preparing for your Spring Boot interview. Go through the common interview questions and answers on Spring Boot that starts from the basic of Spring boot, talks about its features, its working, interceptors and how to implement them. These Spring Boot interview questions and answers for experienced and freshers are curated by our team of industry experts which will help you get hired as a Java Spring Boot Developer, Java architect, and other top profiles.

  • 4.5 Rating
  • 85 Question(s)
  • 60 Mins of Read
  • 9800 Reader(s)

Beginner

Spring Boot is an open source Java-based spring framework, which ease to develop a stand-alone and production ready micro service-based applications:

  • Spring boot is a combination of spring framework, embedded HTTP servers and configuration annotation

Spring boot

  • It follows “Opinionated Defaults Configuration” Approach to avoid lot of boilerplate code and configuration to improve Development, Unit Test and Integration Test Process.
  • Spring boot reduce Development, Unit Test and Integration Test time and to ease the development of Production ready web applications.
  • Spring boot comes with auto configuration, for instance, we must mention the dependency it will configure the spring boot accordingly, just we need to add the @EnableAutoConfiguration annotation
  • Spring boot support both Java and Groovy. 
  • Spring boot also support Spring Initializer to generate the base project.
  • @SpringBootApplication annotation requires to configure the spring boot application.
  • Spring boot embedded HTTP server generally run on 8081 server port.

Spring boot ease and simplify the development of rest full web service and provide a quicker development technique by using the key features provided by spring boot framework.

Spring boot is predominately used to develop the micros services-based application, most of the key features leverage to ease the configuration development and deployment of the microservices architecture.

  • Spring boot comes with the monitoring tool called as an Actuator which does the health check of spring boot production application.
  • Externalised configuration 

@Value("${cassandra.password}")

private String password;

  • Embedded server’s support for example Tomcat, Jetty.
  • No need to deploy the war file, simply run it.
  • Provide convention over configuration using Auto-Configuration feature, example like below annotation.

@EnableAutoConfiguration

@ComponentScan 

  • Support Feign Integration which is basically an HTTP client. To enable this feature, we need to add the org.springframework.cloud:spring-cloud-starter-feign  maven dependency.

There are significant advantages of using spring boot over the JAX-RS which is listed below.

  • Easy deployment
  • Simple scalability
  • Compatible with Containers
  • Minimum configuration
  • Lesser production time
  • Easy to understand, develop and configure the spring application
  • Increase the productivity 
  • Reduce the development time.
  • Provide the health check and monitoring feature.
  • Easy to orchestrate using docker.

All this advantage makes spring boot is one of best alternative to develop the microservices application, along with one of the key benefits is, to make it compatible to use the other framework like messaging services, hibernate and spring cloud.

Besides advantages, there are few issues, where we should think about to adopt the spring boot framework to develop the microservice based architecture. 

  • Spring boot unnecessary increase the size of the build with unused dependencies.
  • Not able to create the war file manually and difficult to configure externally.
  • Doesn’t provide much control and tuning the running build.
  • It’s only suitable for micro-services which eventually need to deploy in docker, but not large or mono lithics web services. 

Spring boot doesn’t provide good compatibility if we are integrating third party framework. 

Spring boot provides good compatibility with other spring frameworks which is used to provide the security, persistency features. Spring boot provides good support with docker containerization, which makes it a good choice to deploy the microservice based application and easy to maintain.

  • Provide the easiest way to configure the java beans.
  • Provide a powerful batch processing and manage rest endpoints.
  • Provide auto-configuration mechanism, that means no manual configuration needed. 
  • Provide annotation-based configuration, so no need to configure the xml file manually.
  • Ease the dependency management.
  • It includes the Embedded servlet container.  

Spring boot comes with spring cloud framework, which has many libraries which are used to handle all types of nonfunctional requirement, which is usually not available in other frameworks.

Spring boot provides many abstraction layers to ease the development, underneath there are vital libraries which work for us. 

Below is the key function performing internally.

  • Using @EnableAutoConfigure annotation the spring boot application configures the spring boot application automatically. 
  • E.g. If you need MySQL DB in your project, but you haven’t configured any database connection, in that case, Spring boot auto configures as in memory database.
  • The entry point of spring boot application is a class which contains @SpringBootApplication annotation and has the main method.
  • Spring boot scan all the components included in the project by using @ComponentScan annotation.
  • Let’s say we need the Spring and JPA for database connection, then we no need to add the individual dependency we can simply add the spring-boot-starter-data-jpa in the project.
  • Spring boot follows the naming convention for dependency like spring-boot-starter. 

Considering above there are other internal functions which play a significant role in spring boot.

Below are the key dependencies which you need to add in maven based or Gradle based applications, to make the application compatible to use spring boot functionality. 

  • spring-boot-starter-parent
  • spring-boot-starter-web
  • spring-boot-starter-actuator
  • spring-boot-starter-security
  • spring-boot-starter-test
  • spring-boot-maven-plugin

These dependencies come with associated child dependencies, which are also downloaded as a part of parent dependencies. 

Below is the basic component, which plays a vital role in spring boot framework for configuration, development, deployment, and execution of microservices based application.

  • Spring boot starter. 
  • Spring boot auto configurator.
  • Spring boot actuator.
  • Spring boot CLI.

Spring boot Initilizr.

Spring boot autoconfiguration, check what are the jars that are available in the classpath, according to that autoconfiguration provides a basic configuration to the application according to that jars or library available.

  • Spring Boot autoconfigurator is used by Spring Boot Framework to provide “Auto-Configuration”.
  • Auto-configuration solves the problem of doing amount of configuration in Spring framework, it detects the dependency in a pom.xml file and according to that it configures the spring boot application.
  • Below is the key annotation which we need to use to enable autoconfiguration

@EnableAutoConfiguration

  • We have a below option to enable the specific class to autoconfigure with the existing application.

@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })

  • If we need to enable the external properties file, we can use the below annotation.

@EnableConfigurationProperties(MySQLDataSourceProperties.class)

  • Below annotation works when there is no bean available in the class path than its configure with configure bean class.

@ConditionalOnMissingBean

Spring boot autoconfigurationSpring boot autoconfiguration brings certain level of intelligence into the application so that it removes the hurdles to provide the configuration manually. One can debug the spring boot application by using the below approach:

  • Switch on the debug logging
  • Trigger the spring boot actuator 

Spring boot starter comprises of templates which provide a Rapid Application Development, spring boot starter contains a combination of all the relevant transitive dependencies.  

  • Spring boot starter is a jar file which predominantly solves the auto-dependency resolution in a spring boot application. 
  • Spring boot starter follows the unified pattern, like every dependency start with spring-boot-starter-X, where X will be the name of dependencies.  
  • For instance, if we add the dependency like spring-boot-starter-web, the spring boot starter will internally resolve and download all the associated dependencies, add to the application. 
  • Spring boot also checks and resolves the transitive dependencies internally.

Spring boot starter

Below are some of the popular Spring boot starters:

  • Spring-boot-starter-web
  • Spring-boot-starter-mvc
  • Spring-boot-starter-security
  • Spring-boot-starter-jpa
  • Spring-boot-starter-tomcat
  • Spring-boot-starter-jetty
  • Spring-boot-starter-json

Spring boot CLI is a command line interface, which use and run test the microservices application based on spring boot.

  • Spring Boot CLI is a module of Spring boot application which use to run and test Spring Boot applications from the command prompt.
  • When we run Spring Boot applications using CLI, then it internally uses Spring Boot Starter and Spring Boot Autoconfiguration components to resolve all dependencies and execute the application.
  • Internally contains Groovy file which is a JAR Dependency Manager to add Spring Boot Defaults and resolve all dependencies automatically. 
  • Spring Boot CLI operation is a combination of below component:
  • Auto Dependency Resolution 
  • Auto-Configuration
  • Management Endpoints
  • Embedded HTTP Servers

Microservices application based on spring boot

The benefits that we achieved from using spring boot CLI is, that we don’t need to use any import, no need to do the xml configuration, no web.xml and no dispatcherservlet declaration and no need to create war file manually.

Spring boot Initilizr is a web application which use to generate the common templates of spring boot application according to the configuration providing in the user interface.

  • Spring boot Initilizr provides a UI where we need to mention the below information.
  • Group
  • Artifact
  • Required dependencies
  • According to the above information, it creates a maven based spring boot project for ready to use.
  • Spring Initilizr also supports the gradle build tools.
  • Spring Initilizr supports the language such as Java, Groovy, Kotlin to develop the spring boot application.  
  • URL for spring Initilizr is https://start.spring.io/
  • Below is the User interface for same.

 All the configurations mentioned at the time of generation of spring boot application will reflect in a pom.xml file, also provided the typical uniform architecture of the project

Spring boot interceptor is typically used to intercept the request and response call made by the UI and microservices-based application, the need of this to add, filter, modified the information contain in request and response.

  • Interceptor in Spring Boot one can use to add the request header before sending the request to the controller 
  • Interceptor in Spring Boot can add the response header before sending the response to the client.
  • Spring boot works on the below technique. 
    • Before sending the request to the controller
    • Before sending the response to the client
    • After completing the request and response.

The real-world use case of spring-boot interceptor is authentication and authorization, where   we filter the information from the request which contain the credential information which use to authenticate and other information like role which require authorization. 

  • @RestController: Define at class level, so that spring container will consider as RestENd point
  • @RequestMapping(value = "/products"): Define the REST URL for method level.
  • @PathVariable:  Define as a method argument
  • @RequestBody:  Define as a method argument
  • @ResponseEntity: To convert the domain object into the response format
  • @hasAuthority:     To grant the access of corresponding endpoints 
  • @GetMapping: To make endpoint compatible for get request.
  • @PostMapping: To make endpoint compatible for post request.
  • @PutMapping: To make endpoint compatible for put request.
  • @DeleteMapping: To make endpoint compatible for delete request.
  • @ResponseStatus:  To generate the HTTP status.
  • @ResponseBody:  To Generate the response message.

Spring Boot is a framework built on top of Spring framework. It eases out configuring & setting up of applications. This is not true not only for standalone applications but also for web-based applications. It reduces boilerplate code and minimizes the spring configuration a lot.

It scans the libraries on its classpath and automatically configures the required classes. This gets us started without writing much code.

Most of the times, Spring boot sets up the default configuration for libraries on its classpath. If your requirement is different from default configuration & setup, Spring boot provides an easy way of overriding the defaults. For example, let’s say you have a Spring Data library on the classpath. In this case, Spring Boot automatically sets up a connection to Database along with Data Source class. Let’s say if you want to change the port where the database is running, Spring Boot provides an easy way of configuring or overriding it. You can set up those in the application.properties ( or YAML /XML).

Spring Boot also provides opinionated Spring-based third-party libraries. They are known as Starters. The advantage is that a starter has all third party dependencies included hence this minimizes the configuration in the application. Secondly, starters also provide default setup & configuration which eases out the integration of the library into the application and get started.

  • Eases Development of Spring Based Applications
  • Eases Bootstrapping of Spring Based Applications
  • Eases Development, Unit Testing & Integration Test Process.
  • Provides opinionated starters which simplify build & configuration
  • Uses Code by Convention to reduce a lot of boilerplate code and Configurations.

 For example, to create a web application using Spring, you will need the following maven dependencies:

<dependency> 
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>xxx</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>xxx</version>
</dependency>

While with Spring boot, it reduces to :

  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>SPRING_BOOT_VERSION_xxx</version>
</dependency>

Not only spring Dependencies, but you also get free Embedded Tomcat Servlet Container with this, you can override this with Jetty or Undertow.

Some of the commonly used are:

  • Spring-boot-starter-web
  • Spring-boot-starter-test
  • Spring-boot-starter-security
  • Spring-boot-starter-data-jpa
  • Spring-boot-starter-thymeleaf
  • spring-boot-starter-actuator
  • Provides default for Configuration ( Code & Annotations)
  • Reduces Development Time 
  • Increases Productivity
  • Eases integration with other Spring Components like Spring JDBC, Spring ORM, Spring Data, Spring Security, Spring Cloud etc
  • Eases testing of Java/Groovy applications from the command line by Providing Command-line Interface
  • Eases the creation of Standalone or Production-ready Applications
  • Provide inbuilt non-functional features ( Security, Embedded Servers, metrics, health checks, externalized configurations) 
  • Eases building of MicroServices based Applications because of its easy integration with spring web, spring cloud etc
  • Eradicates XML configuration or keep it to a minimum.

Main Spring Boot class typically looks like:

@SpringBootApplication
public class SpringBoot1Application {
public static void main(String[] args) {
SpringApplication.run(SpringBoot1Application.class, args);
}
}

As you can see above, the main method calls static run() method SpringApplication class and provides itself(the SpringBoot1Application.class) & args. Now the class supplied (SpringBoot1Application.class) is annotated with @SpringBootApplication.

Now, SpringBootApplication annotation is defined as :

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM,
classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

Where @SpringBootConfiguration is a wrapper Annotation over @Configuration.

Considering this, the Application will now look for classes annotated with @Configuration for setting up the configuration & context.

For example, a typical configuration might look like:

@Configuration
public class MyConfiguration {
@Bean
public MyBean1 myBean()
{
return new MyBean1();
}
@Bean
public MyBean2 myBean()
{
return new MyBean2();
}
@Bean
public MyBean1 myBean()
{
return new MyBean1();
}
}

This configuration creates and registers an instance of beans MyBean1, MyBean2 & MyBean3 so that they can be injected in your application classes and used. 

@ComponentScan instructs the application to scan all ( or filtered if configured so) to look for classes annotated with @Service, @Component, @Repository & @Controller and register them.

You can use include/exclude filters to narrow down the scan.

@EnableAutoConfiguration instructs the application to go with default configuration for the boot starters. For example, the default port for the embedded tomcat server is 8080. 

So to summarize, at bootstrap, your application for @Configuration & initializes and registers configuration. It also looks for components in your packages using ComponentScan and registers them (Building the ApplicationContext). Finally, it executes code which initializes configuration with default configuration for the boot starters that you included.

@SpringBootApplication annotation is not mandatory, it is possible to have a Spring boot based application without using it.

You will do that when you don’t want to go with implicit features provided by @SpringBootApplication annotation.

SpringBootApplication annotation is defined as :

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM,
classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

Let’s say you don’t want to use component scan in your application but would like to go with enabling feature that executes the code for dependencies with default configuration (@EnableAutoConfiguration) 

You can probably define your class as :

 @Configuration
@EnableAutoConfiguration
@Import({ MyConfiguration1.class, MyConfiguration2.class,MyConfiguration3.class })
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}

Here MySpringBootApplication is Spring boot based Application however it does not go with component scan instead it looks for specific configuration classes and import them to set up the configuration.

Another Application may use the following configuration :

@Configuration
@ComponentScan(basePackages = "com.example.demo.components")
public class MySpringBootApplication2 {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication2.class, args);
}
}

Here application wanted to avoid using @EnableAutoConfiguration however it still wanted to components can feature hence MySpringBootApplication2 class definition includes that.

If you use @SpringBootApplication annotation, it brings in default Component scan which will scan the root or base packages where your main class annotated with @SpringBootApplication is located and all its sub-packages. It will also consider your main class as one of the configuration classes as it is annotated (implicitly) with @Configuration ( This is included by @SpringBootApplication annotation).

This is equivalent to the following definition :

@Configuration
@ComponentScan
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}

Typically, in your application, you may want to limit the component scan to certain packages. You can achieve that by specifying the base package, for example,

@ComponentScan("com.example.demo.myapp")

This will scan for all Spring components inside com.example.demo.myapp package ( When we say Spring Components we mean Classes annotated with @Service, @Component, @Repository & @Controller etc.)

If you would like to scan multiple packages, it would be :

@ComponentScan({"com.example.demo.myapp1",”com.example.demo.myapp2”})

Type-safe alternative would be :

@ComponentScan(basePackageClasses = {com.example.demo.myapp1.Example1.class, com.example.demo.myapp2.Example2.class})

Here Example1.class acts as a marker class for package com.example.demo.myapp1 , when you specify this class , it will scan all other classes from the package com.example.demo.myapp1 along with Exmaple1.class. Similar is the case for myapp2 package.

@ComponentScan(basePackages = "com.mypackage",
     includeFilters = @Filter(type = FilterType.REGEX, pattern="com.mypackage.*.*subpackage"),
     excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = NotToBeScannedClass.class)) 

Here Regex FilterType is used for inclusion which means any class whose package matches the pattern (com.mypackage.*.*subpackage) will be included in the scan while using AssignableType Filter, we have specified that a particular class should not be included in scanning.

@ComponentScan(basePackages = "com.mypackage",
      includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = MyCustomAnnotation.class)})

MyAnnotation is defined as :

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {
}

Here any class that is annotated with MyCustomAnnotation annotation will be included in the scan.

The actuator provides built-in features to your application which are production-ready. It provides web endpoints for each of this feature. Some of the most common Spring Boot Actuator endpoints:

  • /health: It shows application health information.
  • /info: It shows arbitrary application info.
  • /metrics: It shows all metrics related information for the current application.
  • /trace: It shows trace information for last few HTTP requests.
  • /beans: It lists all Spring beans in your application.
  • /threaddump: Performs thread dump.
  • /env: Displays a list of properties in the current environment.

For example, when using MicroServices, you will definitely a health check for your microservice as your service registry/Load Balancer need to be updated with only live or healthy services so that any incoming request to your application goes to live node/server only. Instead of building your own health endpoint, you can just import the Spring Boot Actuator and use the built-in health endpoint.

If you need to your own health endpoint, you can do so by implementing health() method from org.springframework.boot.actuate.health.HealthIndicator.

To implement your own endpoint, you can implement org.springframework.boot.actuate.endpoint interface.

With Spring Boot Actuator 2.X, all endpoints except health and Info are disabled. To enable them you need to  set management.endpoints.web.exposure.include=*. 

You can achieve this by adding a starter dependency for DEV tools.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <version>2.1.6.RELEASE</version>
</dependency>

This is a very helpful feature in development, as it gives immediate feedback for code changes. This enhances the productivity of developers to a great extent by saving time in restarts.

This is not a production-ready tool or feature and will be automatically disabled when running in production.

Applications using DevTools restart whenever a file on the classpath is modified.

Spring Boot DevTools provide the following additional features :

  1. You may need a way to configure global settings which are not tied to a particular application. Spring-boot-dev tools supports this by providing a global file is called .spring-boot-dev tools.properties. You can store all such global settings in this file.
  2. Remote Debugging via HTTP :

To enable remote Debugging via HTTP, make sure you have following settings inside pom file 

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludeDevtools>false</excludeDevtools>
            </configuration>
        </plugin>
    </plugins>
</build>

Now when starting application , add following parameters to enable remote debugging :

-Xdebug -Xrunjdwp:server=y,transport=dt_socket,suspend=n

To change port for debugger , add following to application.properties file ( configuration file ) :

spring.devtools.remote.debug.local-port=8010

The default debugger port is 8000.

With a Spring Boot Application, you can fallback to Spring Security. Include the Spring Security Boot Starter :

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.1.6.RELEASE</version>
</dependency>
You can go with HTTP basic or form login.

To update the username or password , override the following properties in application properties file :

Spring.security.user.name = username1

Spring.security.user.password = password1

To enable method level security, you can use @EnableGlobalMethodSecurity.

To disable default Security configuration in-built, you need to exclude SecurityAutoConfiguration class as follows :

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })

public class SpringBootApplication1 {

    public static void main(String[] args) {

        SpringApplication.run(SpringBootApplication1.class, args);

    }

}

This can be also achieved by adding following to properties file :

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration

@ConfigurationTo Override default Security you can implement WebSecurityConfigurerAdapter class , 

for example :

@EnableWebSecurity
public class BasicConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth)
      throws Exception {
        auth
          .inMemoryAuthentication()
          .withUser("username")
            .password("password1")
            .roles("GUEST")
            .and()
          .withUser("admin")
            .password("admin")
            .roles("GUEST", "ADMIN");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        HTTP
          .authorizeRequests()
          .anyRequest()
          .authenticated()
          .and()
          .httpBasic();
    }
}

@EnableWebSecurity is optional if the default security configuration is disabled.

Oauth2 is commonly used for authorization. To integrated OAuth2:

  • Add a starter for Oauth2
  • Use @EnableAuthrizationServer
  • Use @EnableResourceServer in an application where resource located 
  • On Client Side, use either of  @EnableOAuth2Sso or @EnableOAuth2Client.

Following are the features of Spring Boot :

  • AutoConfiguration 

Spring Boot scans the libraries available on the also scans existing configuration for the given application and then provides default configuration ( going by convention) for the library with Application. Think of this as it actually initializes library on the classpath with default values. These libraries are nothing but Spring Boot Starters which may execute some code on startup as well.

For example, when you include a spring boot starter web dependency, from a coding point of view you will see spring mvc is available to you so that you can define REST endpoints or so, you can import @RestController, @RequestMapping etc to build REST endpoints for the application. 

However, from an application point of view, you will set that at startup, dispatcherservlet and a default error page is autoconfigured. What’s more, embedded Tomcat is configured to run at default port 8080 and application gets deployed at 8080. 

So see how Spring Boot makes life easy for Developers! 

Now, the developer needs to think about setting up web.xml or setting up a Tomcat server. He/She can concentrate on an actual application which is drafting REST endpoints & writing Business Logic.

This example was with respect to Web dependency but the same is true for each and every dependency. This is helpful even in case of Proof of Concept carried out by Developers as configuration work is minimized because of AutoConfiguration.

  • Starters libraries

Spring Boot starter libraries is a list of dependency Starters that gets you (quick)        

started on using a particular feature in the application. A starter library is nothing but a wrapper built around the dependency libraries. It is a one-stop-shop for the feature & takes care of including the required dependencies.  It basically carries out 2 things for you :

  • First, of course, gets all the dependencies required ( Dependency Management for that Feature)
  • The Starters generally comes with initialization code assuming few defaults to get you started quickly.

Advantages of Using Spring Boot Starters :

  • The Dependency configurations & the starter itself are well tested and production-ready
  • Eases pom manageability
  • Decreases the Boilerplate code to a large extent
  • Decreases the application Configuration to a large extent.
  • Spring Boot Command Line interface

Spring Boot CLI lets you write & run Groovy Scripts.

For example, let’s assume the following content in app.groovy

@RestController
class GroovyScript {
@RequestMapping("/")
String home() {
"Welcome to Spring Boot!"
}
}

You can then run this as 

spring run app.groovy

Visit localhost:8080 to see the Welcome Message.

  • Actuator

The actuator provides built-in features to your application which are production-ready. It provides web endpoints for each of this feature. Some of the most common Spring Boot Actuator endpoints:

  • /health: It shows application health information
  • /beans: It lists all Spring beans in your application
  • /trace: It shows trace information for last few HTTP requests
  • /env: Displays a list of properties in the current environment
  • /info: It shows arbitrary application info
  • /metrics: It shows all metrics related information for the current application
  • /threaddump: Performs thread dump.

One of the ways to generate the Spring Boot based Project is using Spring Initializer. For this, visit https://start.spring.io/ and select appropriate parameters. This includes selecting build tool (Maven or Gradle), selecting the Language ( Java, Groovy or Kotlin), selecting the Spring Boot version, entering metadata like Group name, artefact name, package name, java version, release artefact type (Jar, War) etc. There is a final section where you can select various Spring Boot Starters, for example, Web Starter or Security Starter

Once all this detail is filled in, you can click on Generate Project to get a Zipped Spring Boot created.

An alternative to this is to use Spring Tools 4 for Eclipse ( IDE). With this, you can generate a Spring Boot Project direct inside IDE. From File Menu, click on New and then select other. Now look for Spring Starter Project, once found, click on it.

Now Click on Finish and a new Spring Boot Project will be created.

Spring Boot CLI is a command-line abstraction that allows us to easily run Spring microservices expressed as Groovy scripts. It also provides simplified and enhanced dependency management for those services.

Spring Boot CLI provides a feature called Shell from where you can execute commands. To start an embedded shell, run the following command:

spring shell

Now, if you want to run a groovy script called app.groovy then you can run it using the command :

run app.groovy

 Or if you would like to know the spring version, the command is :

version

Advantages of using Spring Boot CLI :

  • It is an easy interface to run your Spring Boot application 
  • You can use it to test the Spring Boot application from the command prompt.
  • It has a Groovy compiler and Grape dependency manager.
  • Spring Boot Starter and AutoConfigurate components are used to resolve the dependencies and run the application.
  • Support for Groovy scripts without any installation.

Spring Boot starters help you to avoid defining a set of dependency descriptors. Spring Boot Starters automatically includes the required dependencies for the said feature so that you don't have to go through the cumbersome process of defining the dependencies in your application. Beyond the ease of dependency descriptors, it also relieves you from a lot of boilerplate code. Thus, when you include the Starters you do not need to hunt through sample code and copy-paste dependency descriptors. Secondly, Spring Boot Starters also give you initial setup or initialization of the said feature. This enables the developer to get quickly started on the new feature.

Let’s try to understand this with an example:

You have a requirement to develop a new application that exposed REST endpoints for the user. It also has a requirement to connect to a database for fetching data. Let’s try to simulate this without Spring Boot first. In this case, you will need to add dependencies for Spring MVC, Jackson. You will also need to download and install Tomcat Web Server where you can deploy this new application. Additionally, you also need to configure Tomcat in your favourite IDE ( Eclipse or any other IDE) so that you can run the application from IDE itself.

So many things, right? With Spring Boot around, you can just add a dependency for Spring Boot Web Starter and you are done.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

You can annotate your classes with @RestController , @RquestMapping, @GET, @POST as Spring Rest library has been imported . You can just run application as Spring Boot mode and it will use embedded Tomcat Server to deploy your application , your application will be up and running at localhost:8080.

By default, application properties will sit inside src/main/resources of your Spring Boot Application. You can have multiple properties file, one per environment and one default properties file. 

For example, you may have :

application.properties 
         application-dev.properites
application-int.properites
         application-perf.properites
application-uat.properites
application-prod.properites

Now, depending on the value of Spring profile, the appropriate file would be selected for reference (along with with environment independent file, application.properties ). So what you get at any environment is a merger of application.properties and environment-specific properties. It means if the same property exists in the application.properties file, then the one from an environment-specific file will get higher precedence hence later overrides the former.

Spring boot supports properties, YAML or XML format. Spring Boot advocates 12-factor app principle of externalizing the configuration. What it means, you can have these key-value pairs in external property repository and Spring Boot supports not only fetching the properties from those repositories but also refreshing the values when value changes at the repository.

There are 3 ways Spring Boot supports this:

1. Pull Approach 

In this approach, let’s consider your properties file are residing in the git repository ( True source of Properties file).  You can mark a property ready for a dynamic refresh ( without restarting the application) by using @RefreshScope.

(org.springframework.cloud.context.scope.refresh.RefreshScope).

You can use spring-cloud-config-server dependency to host these files to a server using a simple Spring Boot Application. In this spring boot application, you can use the following property to connect to the git repository:

spring.cloud.config.server.git.uri=https://github.com/your-repo/config-server-repo.git

And in actual application, make use of spring-cloud-starter-config dependency to connect your application to the server where these files are hosted. Your service will read these files from the hosted server. In your application, you need to provide the URL where these property files are   for example:

spring.cloud.config.uri=http://host1:8888

Whenever the value of any property goes, you can hit /refresh endpoint (provided by the actuator) on the application, this will be a POST request. Once the request is executed, the application will refresh all those properties marked for dynamic change will be refreshed.

2. Using a Push Approach 

In this approach, you use Spring-Cloud-Bus dependency and message broker ( let’s say RabbitMQ). Your config-server still points to the git repository. However, you use spring-cloud-starter-bus-amqp dependency to establish the communication between the config server & your application. This dependency needs to be included in both, your application & Config Server.

Embedded Server(in context of Spring Boot) means a Web Server that comes in-built with Spring Boot. Spring Boot supports 3 web servers :

  • Tomcat (This is a default web server . In fact when you include Spring Boot web starter dependency, you get this without any more configuration)
  • Jetty: To override the default and include this, you can use spring-boot-starter-jetty dependency. At the same time, make sure you exclude tomcat web server dependency (default).
  • Undertow: This is another webserver supported by Spring Boot. To include this, you can use spring-boot-starter-undertow dependency.

If you would like to disable the web starter, you can do so by adding the following property to application.properties :

spring.main.web-application-type=none

This is how you can customize/override various default properties associated with the webserver:

  • Port 

You can override port by specifying it in application properties as :

server.port =8081

You can also override by including it as an environment variable(SERVER_PORT=8081).

To disable , HTTP port set :

server.port=-1

While, if you want to look for the best open port, use :

server.port=0

  • HTTP response Compression 

Use the following in property file :

server.compression.enabled=true

  • SSL 

SSL can be configured by setting appropriate properties in application.properties file , for example :

server.ssl.key-store=classpath:keystore.jks

server.ssl.key-store-password=secret

server.ssl.key-password=another-secret

Intermediate

Spring Boot has been built on top of Spring framework. By using it we can skip writing the boilerplate code like configuring the Database or Messaging Queues, XML configurations, setting build path and maven dependencies. Spring Boot can be assumed as the upgradation of existing Spring functionalities to make it robust and easy to use; that is required for building modern cloud applications.

Spring Boot provides an opinionated view by making certain elementary decisions while developing and running the application. Spring Boot uses sensible defaults, mostly based on the classpath contents. For example, Spring Boot sets up JPA Entity Manager Factory if JPA dependencies are in the classpath. However, it provides us the ability to override the defaults as and when required.

Another important aspect of Spring Boot is embedded servers. Traditionally, with Java web applications we build a WAR or EAR file and deploy them into servers like Tomcat or JBoss etc. Hence, we need to pre-install a web/application server before deploying the WAR/EAR files. Whereas in Spring Boot the web server (Tomcat or Jetty) is part of the application JAR. To deploy applications using embedded servers, it is sufficient if; Java is installed on the server.

Spring Boot is considered as the future of Spring, with most of the cloud-based Microservices being built on it. Most of the upcoming Spring projects are completely integrated with Boot like example Spring Cloud Contracts, Spring Boot Admin, etc. required for cloud application development.

With monolithic application development age, programmers and managers had the comfort of taking ample time for setting up the framework, dependencies and defining all processes. However, in the era of microservices and with the agile development process, the expectation is to build the applications consistent and faster. Spring Boot project aims to solve this problem by providing intelligent defaults and embedded servers.

Spring Boot makes it easy to create standalone, production-grade Microservices applications that we can just run. It provides Starter Projects, which are a set of dependencies that we can include in the application. We get a one-stop-shop for all the Spring and cloud-related technologies like Spring Boot Starter Web for developing a web application or an application to expose restful services, Spring Cloud Config, Spring Actuator, etc.

Inversion of Control (IoC) is a concept or principle where the control flow of a program is inverted i.e. instead of the program, the framework takes control of creating and proving objects as required. Spring IoC is responsible for creating the objects, wiring them as per the configuration and managing the complete lifecycle from creation till destruction.

IoC can be implemented using two techniques namely Dependency Lookup and Dependency Injection.

Dependency Lookup is a traditional approach where a component must acquire a reference to a dependency. It helps in decoupling the components of the application but adds complexity in the form of the additional code that is required to couple these components back together to perform tasks.

This is the reason; Dependency Injection is considered a more viable and popular approach to implement IoC in Spring-based applications.

Dependency Injection (DI) is a pattern that implements Inversion of Control, removing the dependency from the code and instead have the framework or container deal with it. Dependency Injection makes code loosely coupled, which makes the application easy to manage and test.

A typical Java application is composed of several objects that collaborate with each other to execute business logic. Traditionally each object is responsible for obtaining its own reference to the dependent objects. For example, a Service class will depend on the DAO class to get data from the database. Service class would directly create an instance of DAO class by using code like “new DAO()”. This introduces tight coupling between Service and DAO classes. This is where the Spring framework comes into rescue by removing tight coupling between the classes. In the above example, the Spring framework would inject a DAO object into Service class. This also allows us to replace the existing Database with another as and when required with minimal code changes.

Dependency Injection provides dependencies to objects at run time rather than compile time, hence making them loosely coupled. Using this concept programmer does not create objects directly but describes how they should be created. The Code doesn’t need to connect the components and services together but just describe which services are needed by which components. Spring container will then hook them up.

Spring framework provides two mechanisms for dependency injection:

Constructor Based: It is implemented when a constructor of the class is defined with a number of arguments each representing a dependency on other class. The Spring container will inject the dependencies while invoking the class constructor at start-up.

Setter Based: It is implemented when a setter method is created for the dependency of the other class, however, this method needs to be invoked explicitly.

Bean is used to refer to any component (POJO class) that is created and managed by Spring’s Dependency Injection container. Ideally, a bean should adhere to the JavaBeans specification, but this is not mandatory, especially when using Constructor-based DI to wire the beans together. In general, any Spring-managed resource can be referred to as a bean which acts as the backbone of the application. Beans can be defined either by using XML configuration or by using Annotations like @Component, @Service, @Controller, @Repository on top of the class definition.

A class can access beans either by injecting it directly or by injecting a bean that has defined a dependency on this bean.

The application can use beans without worrying about creating or destroying the objects.

BeanFactory is responsible for managing components, including their dependencies as well as their life cycles.

BeanFactory is an interface that is the core of Spring’s Dependency Injection container. It is responsible for managing the components (beans), their dependencies and lifecycle.

BeanFactory can be configured using either a configuration XML file or by programmatically which is the case with Spring Boot. It creates a unique identifier for each Bean in the application.

BeanFactory is also called basic IOC, whereas ApplicationContext is called Advanced IOC. Although BeanFactory and ApplicationContext both are used to get the beans from IOC container and inject them as per the configuration.

Below are the significant differences in implementation:

  1. BeanFactory uses lazy initialization i.e. it creates a singleton bean only when it is requested; whereas ApplicationContext uses eager initialization as it creates all singleton beans at the time of initialization.
  2. ApplicationContext creates and manages resources objects on its own whereas in the case of BeanFactory we need to explicitly provide the resource details.
  3. ApplicationContext supports internationalization but BeanFactory does not.
  4. Annotation-based dependency Injection is not supported by BeanFactory whereas ApplicationContext supports annotations like @PreDestroy, @Autowired, etc.

ApplicationContext is an interface that extends BeanFactory. In addition to providing Dependency Injection, it also provides services like Aspect Oriented Programming (AOP), internationalization (i18n), event handling, etc. It is also referred to as the advanced container used by Spring for storing all the environmental information with regard to an application being managed by Spring. It is read-only at run time but can be reloaded if necessary.

Spring recommends using ApplicationContext in all the scenarios, except when it is critical to the additional few KBs of memory that ApplicationContext consumes.

ApplicationContext provides the following abilities:

  • Bean factory methods for accessing application components.
  • To load file resources in a generic fashion.
  • To publish events to registered listeners.
  • To resolve messages to support internationalization.

@SpringBootApplication is the primary annotation which needs to be added to the Application class or the Main class to the project and enables features like Java-based Spring configuration, component scanning, and auto-configuration. An Application class is used to bootstrap and launch a Spring application from a Java main method. This class automatically creates the ApplicationContext from the classpath, scan the configuration classes and launch the application.

@SpringBootApplication is essentially a combination of below annotations:

  • @Configuration: is used to mark a class as a source of bean definitions.
  • @ComponentScan: is used to have Spring scan the package for @Configuration classes.
  • @EnableAutoConfiguration: to enable Spring to determine the configuration based on the classpath.

Following parameters are accepted in the @SpringBootApplication annotation:

  • exclude: This is used to exclude the list of classes from the auto configuration.
  • excludeNames: To exclude the list of fully qualified class names (class names with package info) from the auto configuration.
  • scanBasePackageClasses: To notify Spring the list of classes that has to be applied for the @ComponentScan.
  • scanBasePackages: To provide a list of packages that have to be applied for the @ComponentScan. 

Example:

package com.example.demoApplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(exclude = { SecurityConfiguration.class })
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

Spring Boot Actuator provides the ability to inspect the internals of an application at runtime. It provides application data on auditing, metrics, bean details, version details, configurations, logger details via REST (HTTP) endpoints. These endpoints help in monitoring and managing a Spring Boot application in production. We can also add custom endpoints apart from the default 16 provided. However, it should not be considered as a replacement for production-grade monitoring solutions though it provides a great starting point.

The Actuator endpoint acts as a root for all other endpoints: http://localhost:8080/application

Below are a few of the significant endpoints exposed:

  1. Environment details:

This endpoint provides information about the operating system, JVM, installation, system environment variables, and the values configured in application properties files.

http://localhost:8080/application/env
  1. Health:

This service provides details of the disk space and status of the application.

http://localhost:8080/application/health
  1. Beans:

This endpoint provides the details about all the beans that are loaded into the Spring context. It provides details like name, scope, type, location, and dependencies of the Bean.

http://localhost:8080/application/beans
  1. Metrics:

This endpoint shows metrics about Server memory, processors; JVM details like a heap, threads, garbage collection, etc.

http://localhost:8080/application/metrics
  1. Debugging:

Below actuator endpoints are exposed for debugging application:

/application/heapdump: Provides a heap dump
/application/trace: Provides a trace of the last few requests serviced by the application
/application/dump: Provides a thread dump

The ideal approach to implement Exception Handling in Spring Boot is by using @ControllerAdvice annotation. It allows the multiple scattered @ExceptionHandler to be consolidated into a single global error handling component. It allows full control over the body of the response as well as the status code by use of ResponseEntity. It allows to handle and define the behavior of several exceptions in the same class so that there is a common source of all application errors. It also allows to map different errors to the same method if desired.

@ExceptionHandler annotation provides a mechanism for handling and defining behavior for the exceptions thrown during the execution of handlers (Controller operations).

@ResponseStatus is used to mark a method or exception with error status code and reason that should be returned to the client. The status code is applied to the HTTP response when the handler method is invoked, or whenever said the exception is thrown.

Example:

ControllerAdvice
public class ErrorHandler {
  @ExceptionHandler(GenericContractException.class)
  @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
  public ResponseEntity<ContractError> handleGenericContractException(
      final GenericContractException ex) {
LOGGER.error("Generic Contract Exception has occurred.");
    ContractError cerr = ex.createContractError();
return status(gcex.getRespCode()).body(cerr);
  }

Below are the significant annotations used for connecting a database with Spring application:

@Repository: This annotation is a specialization of the @Component annotation i.e. automatic component scanning enabled so that Spring imports the beans into a container and inject to dependencies. It is typically used on the DAO (Data Access Object) classes. It also catches persistence related exceptions and rethrows them as Spring’s unified unchecked exception.

@Entity: This annotation is used to indicate that the class is a JPA entity and their state is managed by the underlying Persistence Context. In case @Table annotation is not added, it is assumed that this entity will be mapped to a table, with the same name as the class.

@Table: This is used to map the entity class to a given table. It allows having two different names for the Java class and the Database Table.

@Id: This annotation is added on a field that captures the object ID and is an ideal candidate for the primary key

@Column: This is used to explicitly define the column name, default is field/property name.

@Transactional: It is convenient, readable and recommended an approach to handle transactions in Spring. This annotation defines the scope of a single database transaction, that happens inside the scope of a persistence context. The persistence context is in JPA the EntityManager, with default implemented of Hibernate Session.

Yes, we can create our own custom starters. For instance, if we have an internal library for use within the organization which is used across multiple projects. Then it would be a good practice to create a starter for it and to be used in Spring Boot context. These starters enable developers to avoid lengthy configuration and quickly jumpstart their development by the use of simple annotations. To create our own custom starter, we require to create an auto-configuration class with an auto-configure module and a starter module which will bring all required dependencies using pom.xml or build.gradle. Spring Boot custom starter have certain guidelines for the naming convention. They should not start with Spring Boot and ideally, have a name like “name-spring-boot-starter”.

Aspect Orientated Programming (AOP) is a mechanism for adding certain behavior by virtually breaking the program logic into distinct parts called concerns. This helps in increasing modularity by cross-cutting the concerns. These cross-cutting concerns span across multiple points of an application and are conceptually separate from the application's business logic. For e.g. transaction management, authentication, logging, security, etc.

It is a concept in contrast to Object Oriented Programming (OOPS) and Dependency Injection (DI).

The key unit of modularity in OOPS is the class, whereas in AOP the unit of modularity is the aspect. DI allows the application to decouple the objects from each other and AOP helps to decouple cross-cutting concerns from the objects that they affect.

Spring AOP module provides interceptors to intercept an application. For example, when a method is executed, we can add custom functionality before or after the method is executed.

Below are few important AOP concepts:

  • Aspect: It is a concern that we are trying to implement like logging, transaction management.
  • Advice: It is the specific action that needs to be done i.e. the code to be executed.
  • Pointcut: It is the expression which determines the methods on which Advice should be applied.

Spring Boot provides ‘spring-boot-devtools’ module with features that help the programmers while developing the application. It basically improves the experience of developing a Spring Boot application. One of the key features is automatic reload of application as soon as there is a change; hence developer does not need to stop and start the application each time. The is an intelligent feature as it only reloads the actively developed classes but not the third-party JARs.

Another key feature is that by def,ault it disables the caching of view templates and static files. This enables a developer to see the changes as soon as they make them.

In case, we want to disable any of these features, then we need to set them in an application.yml file. For example -Dspring.devtools.restart.enabled=false will avoid automatic application restart.

Below are a few of the features provided:

  1. Property defaults
  2. Automatic Restart
  3. Live Reload
  4. Global settings
  5. Remote applications

Spring Boot lets us define Application Properties to support us for work in different environments. These properties include parameters like application name, server port number, data source details, profiles, and many other useful properties. Spring Boot supports YAML based properties configurations to run the application.

We can simply put an “application.yml” file in “src/main/resources” directory, and it will be auto-detected.  So, by using this default file, we don’t need to explicitly register a PropertySource, or provide a path to a property file, unlike native Spring where we have explicitly define them.

A sample application.yml file looks like below:

spring:
application:
name: SampleRestService
profiles:
active: prod
server.port = 9090

You can use @SpringBootTest annotation. This is over and above the spring-test module. When you include @SpringBootTest, applicationContext is started.

@RunWith(SpringRunner.class)
@SpringBootTest
public class YourTestClass {

SpringBootTest supports different modes, you can enable anyone of them by using web environment property along with @SpringBootTest. These modes are :

  • RANDOM_PORT: This is providing the real environment. The embedded server is started and listen on a random port. This is the one should be used for the integration test
  • DEFINED_PORT: Loads a WebServerApplicationContext and provides a real web environment.

These two modes are important from an Integration point of view, other modes supported are :

  • MOCK: This is the default mode. Here it  loads a web ApplicationContext and provides a mock environment
  • NONE: Loads an ApplicationContext by using SpringApplication but does not provide any web environment

For example, if you go for RANDOM_PORT, code will look like :

@RunWith(SpringRunner.class)

@SpringBootTest(web environment = SpringBootTest.WebEnvironment.RANDOM_PORT)

public class YourTestClass

@MockBean : 

You can make use of @MockBean to mock a particular service or repository or some bean.

For example,

RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class YourTestClass {
   @MockBean
   private EmployeeRepository employeeRepository;
  @Autowired
   private EmployeeService employeeService;
   @Test
   public void testRetrieveStudentWithMockRepository() throws Exception {
       Optional<Employee> employee = Optional.of( new Employee(1,"Scott"));
       when(employeeRepository.findById(49)).thenReturn(employee);
       assertTrue(employeeService.retrieveStudent(49).getName().contains("Scott"));
   }
}

Using  MockMvc & @AutoConfigureMockMvc: 

You can mock up the http requests using MockMvc & @AutoConfigureMockMvc

For example,

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class YourTestClass {
   @Autowired
   private MockMvc mockMvc;
   @Test
   public void testMethod() throws Exception {
       this.mockMvc.perform(post("/employees")).andExpect(status().is2xxSuccessful());
       this.mockMvc.perform(get("/employee/49")).andDo(print()).andExpect(status().isOk())
         .andExpect(content().string(containsString("Rahul")));
   }
}

Spring Boot offers different ways of running an application.

These are :

Running the Application as Spring Boot Application

1. Running the application in an external Tomcat 

By Packaging the application as War application and deploying it to an external Tomcat web server.

2. Running the application using java -jar  “artifcat_name”.

java -jar target/mydemoapp.jar

To Support remote debugging for this, you can use the following parameters along with the java command :

java -Xdebug -Xrunjdwp:server=y, transport=dt_socket, address=8000,suspend=n \ -jar target/mydemoapp.jar

3. By using Maven or Gradle Plugin

mvn spring-boot:run 

You can use the MAVEN_OPTS environment variable

export MAVEN_OPTS=-Xmx1024m

gradle bootRun

You can use JAVA_OPTS environment variable

export JAVA_OPTS=-Xmx1024m

For Class level conditions, you can have @ConditionalOnClass and @ConditionalOnMissingClass. The @ConditionalOnClass and @ConditionalOnMissingClass annotations let @Configuration classes be included based on the presence or absence of specific classes. For example, using these conditions, Spring will only use configuration MyConfiguration bean if the SomeClass is present on the classpath:

@Configuration
@ConditionalOnClass(SomeClass.class)
class MyConfiguration {
    //...
}

Similarly, in the following example, Spring will only use configuration MyConfiguration bean if the SomeClass is absent on classpath:

@Configuration
@ConditionalOnMissingClass(SomeClass.class)
class MyConfiguration {
    //...
}

Similarly, there is something called, @ConditionalOnBean and @ConditionalOnMissingBean. If the beans specified as part of this annotation are available on classpath then class will be considered for Configuration.

@Bean
@ConditionalOnBean(name = "dependentBean")
Mybean myBean() {
    // ...
}

Here MyBean will be created only if dependentBean exists on classpath, this is very useful to create bean in ApplicationContext.

@Configuration
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService() { ... }
}

Here if myService bean will be created only if no existing my service bean exists in ApplicationContext.

@ConditionalOnProperty

This tells Spring to include Configuration based on property value. This can come to rescue for defining environment-specific beans.

In the following example, the instance of MyBean will be created only if = local.

@Bean
@ConditionalOnProperty(
    name = "usemysql", 
    havingValue = "local"
)
MyBean myBean() {
    // ...
}

If you want to include configuration if a specific resource is present, then you can use @ConditionalOnResource is present.

The @ConditionalOnResource annotation lets configuration be included only when a specific resource is present:

@ConditionalOnResource(resources = "classpath:myproperties.properties")
Properties myProperties() {
    // ...
}

Let’s consider a situation, where you would like to include a particular configuration only if the application is a web application. In such cases, you can use @ConditionalOnWebApplication annotation.

@ConditionalOnWebApplication
MyController myController() {
    // ...
}

Similarly, we have @ConditionalOnNotWebApplication which can be used to include configuration if the application is non-web application.

We have seen various @Condition annotation which are for specific use cases. If we have a general and more complex requirement, we can make use of @Conditional annotation & 

@ConditionalExpression annotation.
@Bean
@ConditionalOnExpression("${isProduction} && ${myserver == weblogic}")
DataSource dataSource() {
    // ...
}

Spring Boot eases quick starting a new feature from an application development point of view. However, what about building, packaging and other life cycle steps of your Spring Boot application. Here, Spring Boot maven plugin comes to your rescue. 

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.6.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

It helps to collect all the jars on the classpath and builds a single, runnable jar ", which makes it more convenient to execute and transport your service.

It searches for the public static void main() method to flag as a runnable class.

The Spring Boot Plugin has the following goals.

spring-boot:run: This is for running your Spring Boot application.

Spring-boot:repackage: This is for repackaging your jar/war to be executable.

spring-boot:start and spring-boot:stop: This can be used for Integration tests.

spring-boot:build-info: This generates build information that can be used by the Actuator.

  • For this, you will extend SpringBootServletInitializer 
@SpringBootApplication
public class MyWebApplication extends SpringBootServletInitializer{
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MyWebApplication.class);
    }
    public static void main(String[] args) {
        SpringApplication.run(MyWebApplication.class, args);
    }
}
  • Packaging Type in pom.xml needs to be defined as :
<packaging>war</packaging>
  • Add spring-boot-starter-tomcat as the provided scope
 <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <scope>provided</scope>
  </dependency>
  • Java Version: Spring Boot 2 requires Java 8 as a minimum version. Spring Boot 1 supports version Java 7 and below. From Spring Boot version 1.4.x, it requires Java 7 however lower versions of supports lower Java versions like Java 6 or so. As far as a recommendation goes, for Spring Boot 1, try to be at least on Java version 7 as much as possible. If you want to use the latest Java release and take advantage of this framework, Spring Boot 2 is the only option for you.
  • Spring Version: If you want to use features of Spring 5, go for Spring Boot 2.
  • BOM ( Bill of Materials): In Spring Boot 2, there has been an upgrade to the dependencies version, the whole list is available here, for example :
    • Gradle minimum version is 3.4
    • Tomcat - version 8.5
    • Hibernate - 5.2
  • Security upgrade

With Spring Boot2, everything is secured, actuator endpoints as well as static resources.

  • New Starters

New Starters for Reactive components like MongoDB, Redis, Cassandra.

  • Spring Boot Actuator Upgrade

All endpoints are now under /actuator endpoint. You can tweak this path by using management.endpoints.web.base-path property.

All are disabled by default( except /health & /info) . To enable you can use management.endpoints.web.exposure.include=* ( or list endpoints to be enabled)

You can easily write a new endpoint using @Endpoint annotation and it will get listed under /actuator.

For example,

@Component
@Endpoint(id = "newapp")
public class NewAppEndpoint {
    private Map<String, NewApp> newAppStore = new ConcurrentHashMap<>();
    @ReadOperation
    public Map<String, NewApp> newApps() {
        return newAppStore;
    }
    @ReadOperation
    public NewApp newApp(@Selector String name) {
        return newAppStore.get(name);
    }
    @WriteOperation
    public void configureNewApp(@Selector String name, NewApp newApp) {
        newAppStore.put(name, newApp);
    }
    @DeleteOperation
    public void deleteNewApp(@Selector String name) {
        newAppStore.remove(name);
    }
    public static class NewApp {
        private Boolean enabled;
    //Other properties & their Setter/Getters..
    }
}

Similarly, we can use @EndPointWebExtension to extend an existing endpoint.

  • Other changes: Gradle Plugin upgrade, most of the configuration start with management.

Hibernates gels well with Spring and with Spring Boot around, it makes the task super easy.  We will see a generic way of Integrating Hibernate using Spring Boot in such a way that switching to some other jpa vendor tomorrow would be super easy.

Let’s start with the process.

1. First thing first, you will need spring-boot-starter-data-jpa.

Since Spring uses Hibernate as default vendor, you really don't need to configure or mention Hibernate explicitly somewhere.

2. Second step would be Drafting the Entity Class. Let’s consider, we are building an application to get a list of employees. So Employee, in this case, would be an Entity for us. You can use @javax.persistence.Entity annotation to define your entity as :

@Entity

public class Employee {

@Id

    @GeneratedValue

private Long id;

private String name;

//……./// Getters & Setters

3. Extend the JpaRepository and define methods ( if required).

Your get all CRUD operations method inbuilt and if you need any additional customized methods, you can define them here.

In our example, we don't need to define any method as a JPA repository does provide findAll() method.

@Repository

public interface EmployeeRepository extends JpaRepository<Employee, Long>{

}

Actually, that’s it, you are done from an Integration point of view. Of course, you will need a few additional things from an operational point of view that we would define below. 

4. Table Naming in Capitals :

For this set following property in application.properties

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

5. For Operational purpose in this example, we are using H2, so for that : 

  a) Include H2 maven dependency in pom.xml 

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>

  b) Enable H2 by setting following property in application.properties 

spring.h2.console.enabled=true

6. Define EmployeeService :

@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public List<Employee> getAllEmployees()
{
return employeeRepository.findAll();
}
}

 7. Include Spring-boot-web-starter in pom.xml abd Define EmployeeController :

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
@RestController
@RequestMapping("/employees")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping
public List<Employee> getAllEmployees()
{
return employeeService.getAllEmployees();
}
}

The Code is available in GitHub @

Now Start the application and hit http://localhost:8080/h2-console

Change JDBC url to “jdbc:h2:mem:testdb”.

Leave others with default values and login and execute the following queries :

insert into EMPLOYEE values(1, ‘Virat’);

insert into EMPLOYEE values(2, ‘Rohit’);

insert into EMPLOYEE values(3, ‘Rahul’);

Now hit the http://localhost:8080/employees endpoint and see the list of employees just entered.

Spring Boot offers a number of features with respect to Messaging. To start with let’s talk about javax.jms.ConnectionFactory.

1. Using ConnectionFactory

This provides an Interface to send & receive messages.

Spring uses JNDI to look for the ConnectionFactory which you can configure by using the following property in application.properties :

spring.jms.jndi-name=java:/MyConnectionFactory

Alternatively, if ActiveMQ Starter is used, Spring Boot will autoconfigure the factory. You can customize the configuration using following properties :

spring.activemq.broker-url=tcp://localhost:9876
spring.activemq.user=activeemq
spring.activemq.password=password
spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=50
spring.jms.cache.session-cache-size=10

How do you send & receive Messages?

To send a message , you can inject org.springframework.jms.core.JmsTemplate into your application bean and use it for sending messages.

For example,

@Component
public class MyMessageBean {
private final JmsTemplate jmsTemplate;
@Autowired
public MyMessageBean(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
} }

You can convert a simple method into Message Listener by using annotation org.springframework.jms.annotation.JMSListener (destination =”myQueue”)

@Component
public class SomeBean {
@JmsListener(destination=”somequeue”)
public void processMessage(String content) {
} }

To override default Connection Factory,

you can make use of DefaultJmsListenerContainerFactoryConfigurer as follows:

@Bean
public DefaultJmsListenerContainerFactory myFactory(
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory =
new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory());
factory.setMessageConverter(myMessageConverter());
return factory;
}

Now your listener would be as follows :

@Component

public class SomeBean {

@JmsListener(destination=”somequeue” containerFactory=”myFactory”)
public void processMessage(String content) {
} }

AMQP is a platform-independent protocol. Spring Boot provides Starter for AMQP spring-boot-starter-amqp.

With this starter imported, if you have RabbitMQ running , Spring Boot will auto configure connection to RabbitMQ from your application. If you want to customize the configuration, you can use:

spring.rabbitmq.host=localhost

spring.rabbitmq.port=5672

spring.rabbitmq.username=admin

spring.rabbitmq.password=secret

Additional Properties for Retry :

spring.rabbitmq.template.retry.enabled=true

spring.rabbitmq.template.retry.initial-interval=2s

You can use AMQPTemplate or RabbitMessagingTemplate for sending messages similar to JMSTemplate. For receiving messages, you can use

 @RabbitListener(queue=”MyQueue”)

@Component

public class SomeBean {

@RabbitListener(destination=”somequeue”)

public void processMessage(String content) {

} }

If you want to override default Connection Factory, you can make use of SimpleRabbitListenerContainerFactoryConfigurer as follows :

@Bean

public SimpleRabbitListenerContainerFactory myFactory(

SimpleRabbitListenerContainerFactoryConfigurer configurer) {

SimpleRabbitListenerContainerFactory factory =

new SimpleRabbitListenerContainerFactory();

configurer.configure(factory, connectionFactory);

factory.setMessageConverter(myMessageConverter());

return factory;

}

In this case , your listener will be changed to :

@Component

public class SomeBean {

@RabbitListener(destination=”somequeue” containerFactory=”myAMQPFactory”)

public void processMessage(String content) {

} }

Spring Boot Admin is a web application that is used for Spring Boot applications management and monitoring. Each application is considered a client and registers to Spring Boot Admin Server. The Spring Boot Actuator endpoints give the magic behind the scenes.

<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-server</artifactId>
    <version>2.1.6</version>
</dependency>
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-server-ui</artifactId>
    <version>2.1.6</version>
</dependency>

With this, what you get for free is @EnableAdminServer, so let’s use this.

@EnableAdminServer
@SpringBootApplication
public class MySpringBootAdminApp {
    public static void main(String[] args) {
        SpringApplication.run(MySpringBootAdminApp.class, args);
    }
}

This sets up our admin server.

Start the Admin Server and see if it is available at localhost:8080/admin/

Now, in your client application , we need a corresponding client which will register to this admin server. Use following in your client application.

<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>2.1.6</version>
</dependency>

Now on the client side, you also need to provide the url where admin server is running. Configure following in your client application’s application.properties:

spring.boot.admin.url=http://localhost:8080

Spring Boot Admin can be configured to only show the data we deem helpful. We just need to change the default setup and add our own required metrics.

For this configure following in application.properties of Spring Boot Admin Server.

spring.boot.admin.routes.endpoints=env, metrics, trace, Jolokia, info, configprops

spring-boot-starter-actuator: This starter is very useful and will be used most especially when you are developing microservices etc. This provides production-ready features to help you monitor and manage your application. It provides a lot of inbuilt endpoints, for example, health endpoint, /env endpoint.

spring-boot-starter-web: Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container

spring-boot-starter-data-jpa: This is for using Spring Data JPA, default vendor is hibernated however you can override it to some other vendor, for example, ibatis.

spring-boot-starter-data-MongoDB: Starter for using MongoDB document-oriented database and Spring Data MongoDB.

Spring-boot-starter-thymeleaf: Starter for building MVC web applications using Thymeleaf views

spring-boot-starter-security: Starter for using Spring Security.

spring-boot-starter-test: Starter for testing Spring Boot applications with libraries including JUnit, Hamcrest and Mockito

You can use logging with Spring Boot by specifying log levels on application.properties file.

Spring Boot, by default, incorporates spring-boot-starter-logging as a transitive reliance for the spring-boot-starter module. By default, Spring Boot incorporates SLF4J with Logback usage.

Presently, if Logback is accessible, Spring Boot will pick it as the logging handler. You can undoubtedly arrange logging levels inside the application.properties document without making logging supplier explicit setup files, for example, logback.xml or log4j.properties.

For example, the configuration is : 

logging.level.org.hibernate=ERROR

logging.level.org.springframework.web=INFO

If you would like to include Log4J or Log4j2, instead of Logback, you can exclude spring-boot-starter-logging and include the respective logging starter, as follows:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j</artifactId>
</dependency>

You will need to add log4j.properties file to the root classpath, Spring Boot will automatically pick it up.

With log configuration, you may see the following things:

  • Source Class name
  • Thread Name /ID
  • Date & Time
  • Log Level ( Debug/Trace/Info/Warn/Error)
  • Actual Log Message

When you generate a Spring Boot Project, you will see following inside your pom.xml file:

   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

This is reference to default Spring Boot Starter or parent Spring Boot Starter. You can use multiple child Projects using the configuration from this. This Starter gives you for free Configuration ( For example,Java Version) , Version of Dependencies ( Dependency Management) and default configuration for plugin.

With parent Project, you get the following features : 

  • Default Compiler Level for Java Version.
  • Plugin configuration (exec plugin, Git commit ID, and shade).
  • UTF-8 source encoding.
  • A Dependency Management section: This is coming from spring-boot-dependencies pom, that manages the versions of common dependencies.
  • Resource filtering.
  • Resource filtering for application.properties and application.yml including environment-specific files (for example, application-dev.properties and application-dev.yml).

Spring Boot Starter Parent has spring-boot-dependencies as the parent pom. It inherits dependency management from spring-boot-dependencies.

   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath>../../spring-boot-dependencies</relativePath>
    </parent>

Minimum Java version is 8 with Spring 2. 

You Can configure the various properties/configuration as under :

<properties>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <resource.delimiter>@</resource.delimiter>
        <maven.compiler.source>1.8</maven.compiler.source>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.target>1.8</maven.compiler.target>
   </properties>

Spring Boot Starter Parent specifies the default configuration for a host of plugins including maven-failsafe-plugin, maven-jar-plugin, maven-surefire-plugin, and maven-war-plugin etc.

In the majority of cases, you will build a Spring Boot application using Spring Boot Starter Parent. However, there could be a case where you need to be very explicit about your dependencies and maven configuration. This could be a case of corporate rules or policies.

In such cases, you may use scope=import to get the benefit of dependency management intact. For example,

<dependencyManagement>
     <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.1.6.release</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Now include the required entries in dependencyManagement section before spring-boot-dependencies .For example,

The next step is we need to add an entry in the dependencyManagement of your project before the spring-boot-dependencies entry. For example, you could add the following element to your pom.xml:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-releasetrain</artifactId>
            <version>Fowler-SR2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.1.0.BUILD-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Swagger is a set of open-source tools that helps with creating documentation for your REST services.

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.4.0</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.4.0</version>
    <scope>compile</scope>
</dependency

This is something you can attach to your methods exposing REST endpoints.

@Api
@RestController
public class MyController {
    @RequestMapping(method = RequestMethod.GET, path = "/welcome")
    @ApiOperation(value = "Welcome<Name> !!",
                    notes = "returns welcome “)
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "Success"),
            @ApiResponse(code = 404, message = "Service not available"),
            @ApiResponse(code = 500, message = "Unexpected Runtime error") })
    public String welcome(@RequestParam(value = "destination", defaultValue = "local") String city) {
        return "Welcome to an event @ " + city;
    }
}

To enable Swagger into your application , you will need the following configuration :

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    public Docket helloApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.ant("/welcome/*"))
                .build();
    }
}

Start the application and to test the application, go to the following URL in the browser :

http://localhost:8080/hello?name=John

It should print “Welcome to an Event @ Singapore”.

For checking the generated Swagger documentation, open this URL in the browser :

http://localhost:8080/swagger-ui.html.

Advanced

Spring boot checks if any class is annotated as @ControllerAdvice and @ExceptionHandler and called from rest end point layer, when any exception occurs than spring boot calls the corresponding annotated class to handle the error message.

  • Spring boot provides the below annotation to create the custom handler which eventually catch the exception from rest endpoint.
  • Spring boot provides the cross-cutting concern to handle the exception being generated by rest layer.
  • Leverage to use the error message code comprehensively. 
  • @ControllerAdvice is an annotation, to handle the exceptions globally.
  • @ExceptionHandler is an annotation used to handle the specific exceptions and sending the custom responses to the client.

The real-time scenario is like, let’s say that most of the exception message is system generated and has a straightforward information, which is sometimes difficult to interpret by the user interface and understand by layman user, to solve this issue spring boot handle the error message and convert into the meaningful and comprehensive message which easy to understand and interpret. 

Interceptor is one of the prominent features of spring boot and must use the @Component annotated class that supports it and it should implement the HandlerInterceptor interface.

There are three methods which are used to implement the interceptor.

  • preHandle() method − This method is predominantly used  to perform the operation by intercepting the call and getting the information present in the request.
  • postHandle() method − This method is used  to perform the operation by intercepting  the call information present in the response.
  • afterCompletion() method − This is used to perform operations when the request and response get completed.

Below code structure represent the main method of spring boot which use to kick start the spring boot application along with the configuration details which is in annotated form.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/* Below code is sample code to run the spring boot application from main method.
*  We have to add the ComponentScan annotation to instantiate the bean for onfigure class.
*  Need to add the EnableAuutoConfiguration to do auto configuraion according to the * *dependencies.  
* SpringBootApplication annotation responsible to make the class as a spring boot application.
*/
@ComponentScan
@EnableAutoConfiguration
@SpringBootApplication
public class SpringBootApplication {
  public static void main(String[] args) {
    // Below syntax use to run the spring boot application with internal configure web server,       //which publish deploy and publish the web services, once this process succcessful and web //seriver is up, the web service is available for the configure request.
     SpringApplication.run(SpringBootApplication.class, args);
  }
}

To run the above code, we have to run the below command either from command prompt or shell: mvn spring-boot: run

Below code structure represent the Rest Controller class developed using spring boot framework which use to act as Http Get method.

// Below series of import is important package specially org.springframework package.
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.practise.springboot.model.Product;
// Need to mention the RestController so that it will behave as rest end point.
@RestController
public class ProductServiceController {
  private static Map<String, Product> productRepo = new HashMap<>();
  static {
     Product honey = new Product();
     honey.setId("1");
     honey.setName("Honey");
     productRepo.put(honey.getId(), honey);
     Product almond = new Product();
     almond.setId("2");
     almond.setName("Almond");
     productRepo.put(almond.getId(), almond);
  }
// Below method act as a GET method, which is responsible to receive the HTTP GET call and return back the Product details as a response along with the HTTP Status OK.
  @RequestMapping(value = "/products",  method = RequestMethod.GET)
  public ResponseEntity<Object> getProduct() {
     return new ResponseEntity<>(productRepo.values(), HttpStatus.OK);
  }
}

Below code structure represent the Rest Controller class developed using spring boot framework which use to act as Http Post method.

import java.util.HashMap;
import java.util.Map;
// Below series of import is important package specially org.springframework package
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.practise.springboot.Product;
// Need to mention the RestController so that it will behave as rest end point.
@RestController
public class ProductServiceController {
  private static Map<String, Product> productRepo = new HashMap<>();
  // Below method works as a POST method, which is responsible to receive the HTTP Post //method call along with RequestBody which has a product information, need to persist in    //Database and will return the HTTP Status as Created.
  @RequestMapping(value = "/products", method = RequestMethod.POST)
  public ResponseEntity<Object> createProduct(@RequestBody Product product) {
     productRepo.post(product.getId(), product);
     return new ResponseEntity<>("Product is created successfully", HttpStatus.CREATED);
  }
}

}

Below code structure represent the Rest Controller class developed using spring boot framework which use to act as Http Put method.

import java.util.HashMap;
import java.util.Map;
// Below series of import is important package specially org.springframework package
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.practise.springboot.Product;
// Need to mention the RestController so that it will behave as rest end point.
@RestController
public class ProductServiceController {
  private static Map<String, Product> productRepo = new HashMap<>();
  // Below method responsible to handle the HTTP PUT request, which will receive the Path
  //variable {id } as a  parameter and responsible to update the database information according
 // to the id parameter.
  @RequestMapping(value = "/products/{id}", method = RequestMethod.PUT)
  public ResponseEntity<Object> updateProduct(@PathVariable("id") String id, @RequestBody Product product) {
     productRepo.remove(id);
     product.setId(id);
     productRepo.put(id, product);
     return new ResponseEntity<>("Product is updated successsfully", HttpStatus.OK);
  }
}

Below code structure represent the Rest Controller class developed using spring boot framework which use to act as Http Delete method.

import java.util.Map;
// Below series of import is important package specially org.springframework package
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.practise.springboot.Product
// Need to mention the RestController so that it will behave as rest end point.
@RestController
public class ProductServiceController {
  private static Map<String, Product> productRepo = new HashMap<>();
 // Below method responsible to handle the HTTP DELETE request, which will receive the Path
  //variable {id } as a  parameter and responsible to delete  the database information according
 // to the id parameter.
  @RequestMapping(value = "/products/{id}", method = RequestMethod.DELETE)
  public ResponseEntity<Object> delete(@PathVariable("id") String id) {
     productRepo.remove(id);
     return new ResponseEntity<>("Product is deleted successsfully", HttpStatus.OK);
  }
}

Below code structure represent the ControllerAdvice  class developed using spring boot framework to handle the  exception.

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
            // Need to mention the RestController so that it will behave as a controller class
@ControllerAdvice
public class ProductExceptionController {
// Below method use to handle the exception, which is being generated by the rent //endpoint method. This method also act as a User define exception.
  @ExceptionHandler(value = ProductNotfoundException.class)
  public ResponseEntity<Object> exception(ProductNotfoundException exception) {
     return new ResponseEntity<>("Product not found", HttpStatus.NOT_FOUND);
  }
}
  1. Rest controller class which generate the exception
import java.util.HashMap;
import java.util.Map;
// Below series of import is important package specially org.springframework package
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.tutorialspoint.demo.exception.ProductNotfoundException;
import com.tutorialspoint.demo.model.Product;
// This class represents how to call the exception handler class which is mention above.
@RestController
public class ProductServiceController {
  private static Map<String, Product> productRepo = new HashMap<>();
  static {
     Product honey = new Product();
     honey.setId("1");
     honey.setName("Honey");
     productRepo.put(honey.getId(), honey);
     Product almond = new Product();
     almond.setId("2");
     almond.setName("Almond");
     productRepo.put(almond.getId(), almond);
  }
  // Below rest end points method throwing the exception if id is not found in databases,   //so rather than call the runtime exception its calling the handler class, to catch the //exception and generate the appropriate message
  @RequestMapping(value = "/products/{id}", method = RequestMethod.PUT)
  public ResponseEntity<Object> updateProduct(@PathVariable("id") String id, @RequestBody Product product) {
     if(!productRepo.containsKey(id))
throw new ProductNotfoundException();
     productRepo.remove(id);
     product.setId(id);
     productRepo.put(id, product);
     return new ResponseEntity<>("Product is updated successfully", HttpStatus.OK);
  }
}

Swagger is a specification and framework implementation for producing a visual representation of RESTful Web Services API. With the help of Swagger, the API consumer can understand and interact with the remote service with a minimal amount of implementation logic. One can compare it to the blueprint of a house.

It creates a contract for the RESTful API, detailing all of its resources and operations in a human and machine-readable format. It allows the documentation to be placed at the same project as the server allowing easy development, discovery, and integration of the application.

It is typically defined in a YAML file, which makes it easy to comprehend both by developers, API clients, and business users, etc. Swagger can be integrated with Gradle for enabling code generation feature, which is used for generating REST controllers and domain classes (POJO) for the application. This helps in maintaining the API definition and code always in sync.

A profile is a feature of Spring framework that allows us to map the beans and components to certain profiles. A profile can be assumed to be a group or an environment like dev, test, prod, etc.; that needs a certain kind of behavior and/or requires to maintain distinct functionalities across the profiles. So, when the application is running with ‘dev’ (Development) profile only certain beans can be loaded and when in ‘prod’ (Production) certain other beans can be loaded.

In Spring Boot we use @Profile annotation to map bean to a particular profile by taking the names of one (or multiple) profiles.

Let’s say we have a Component class that is used to record and mock the REST requests and responses. However, we want to activate this component only in dev profile and disable in all other profiles. We annotate the bean with “dev” profile so that it will only be present in the container during development.

@Component
@Profile("dev")
public class DevMockUtility

Profiles are activated using application.yml in the Spring project:

spring.profiles.active=dev

To set profiles programmatically, we can also use the SpringApplication class:

SpringApplication.setAdditionalProfiles("dev");

Hibernate is a JPA (Java Persistence API) implementation providing ORM (Object-relational mapping) for mapping, storing, updating and retrieving application data from relational databases to Java objects and vice versa. Hibernate maps Java classes to database tables and from Java data types to SQL data types, hence programmer is relieved from writing traditional data persistence programs like SQL.

Whereas Spring Data JPA is a JPA Data Access Abstraction used to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores. With Spring Data, we still need to use Hibernate, Eclipse Link, or any other JPA provider. One of the key benefits is that we can control transaction boundaries with the use of @Transactional annotation.

Circular Dependency in Spring is a situation when a bean depends on another bean, but at the same time, the other bean depends on the first one in turn.

Now when the Spring context is trying to load all the beans, it tries to create beans in the order needed for them to work completely. For example, if we have an application with three beans where bean X depends on bean Y and it depends on bean Z. Spring will create beans in a sequence where bean Z is first created, then create Y with Z been injected to it and finally create X with Y being injected into it.

bean X > bean Y > bean Z

But, in case we have a circular dependency, where bean X depends on bean Y; but Y, in turn, depends on X again.

bean X > bean Y > bean X

Here Spring is unable to determine which bean should be created first since they depend on one another. In this case, Spring will throw a BeanCurrentlyInCreationException while loading the Application context. It can happen if dependencies are not defined properly while using constructor injection as it requires to create and load all the dependencies while loading the context.

Workarounds:

  1. Redesign:

An appropriate redesign of the components in a manner that their hierarchy is well designed can avoid circular dependencies.

  1. Use @Lazy:
@Autowired
    public X (@Lazy Y y) {
        this.y = y;
}
  1. Use Setter/Field Injection:

As setter-based injection loads the dependencies only when required; can help in avoiding error due to a circular dependency.

    @Autowired
    public void setY (Y y) {
        this.y = y;
}

@Bean is used when we want to define a class method as a Spring bean producer. It is used in conjunction with a configuration class (annotated with @Configuration). Here we explicitly declare the Spring beans.

On the other hand, @Component is used in classes, marking it as a source of bean definitions. However, it only works when we enable component scan in the application and the given class is included in it. So, in this case, we let Spring pick up the bean.

Now the end-result for both annotations is the same as Spring will add the beans the context.

However, there are some minor characteristics that can be considered while choosing between @Bean and @Component. Let us consider a scenario where we have a module containing few utility services, that are being shared across multiple applications. Though these services provide nice features, not all of them are needed by each application.

Here, if mark these utility service classes as @Component and set them for component scan in the application, we might end up detecting more beans than necessary. In this case, we either have to adjust the filtering of the component scan or provide configurations where even the unused beans can run.

In this scenario, it would be better to use @Bean annotation and only instantiate the beans, that are required individually in each application.

In a nutshell, we should use @Bean for adding third-party classes to the context, whereas @Component when it is inside the same application.

Caching is a mechanism that helps in reducing roundtrip calls to Database, REST service, files, etc. Performance under heavy load is a key feature expected from any modern web and mobile application, hence caching is really vital to enhance the speed of fetching data.

Spring Boot provides a starter project for caching “spring-boot-starter-cache”, adding this to an application brings in all the dependencies to enable JSR-107 (JCACHE - Java Temporary Caching API) and Spring caching annotations.

In order to enable caching in a Spring Boot application, we need to add @EnableCaching to the required configuration class. This will automatically configure a suitable CacheManager to serve as a provider for the cache.

Example:

@Configuration
@EnableCaching
public class CachingConfig {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("addresses");
}
}

Now to enable caching, we need to add a @Cacheable annotation to the methods where we want to cache the data.

@Cacheable("addresses")
public String getAddress(Customer customer) {...}

While defining a bean, Spring allows us to declare the scope of that bean. The scope describes the life cycle and visibility of that bean in the Application context.

Spring framework supports five scopes with the default scope as a singleton.

The scope can be described using @Scope annotation on any spring bean:

@Service

@Scope("singleton")

public class ServiceImpl implements Service

Singleton:

When a bean is defined with a scope as Singleton, then the container creates only a single instance of that bean. A single object instance is cached and returned for all subsequent requests for this bean. On making any modifications to the object will be reflected in all references to the bean. This is the default scope when no other scope is specified.

However, the singleton scope is one object per Spring container only. So, if we have multiple spring containers running on a single JVM, then there can be multiple instances of the same bean.

Prototype:

A bean defined with prototype scope will return a different instance of an object, every time it is requested from the container. If a bean contains a state, it is recommended that you use the prototype scope for it. It can be defined by setting the value ‘prototype’ to the @Scope annotation in the bean definition. We should use this scope when the object is not usable after a request is completed or requires certain state for each new request.

@RequestMapping: This annotation is used on methods in the controller class to specify the API path and the REST operation type via RequestMethod. This method will be responsible for serving the HTTP request to the given path and return the desired response with the help of desired service classes.

Example:

@RequestMapping(path = "/contract/1.0/contracts", method = RequestMethod.PUT)

@RequestBody: This annotation is used to bind the incoming HTTP request body to the parameter defined in the method annotated with @RequestMapping. Spring uses HTTP Message converters to convert the HTTP request body into a defined domain object

@PathVariable: This annotation is used to get the value from the HTTP URL and capture into the method arguments.

Example:

@RequestMapping(path = "/products/{id}",produces = "application/json")

@RequestParam: This annotation is used to capture values from the HTTP URL based on keys defined in the methods. Spring parse the request parameters and put the appropriate ones into the method arguments.

Example:

@RequestMapping(path = "/products/{id}",produces = "application/json")

public Product getPlan (@PathVariable("id") final String planId,

@RequestParam(value = "q", required = false) final String queryParameters)

REST stands for REpresentational State Transfer. It is a web standards-based architecture using HTTP Protocol for data communication. A REST Server provides access to resources and REST client accesses and modifies the resources. Resources can be text files, HTML pages, images, videos or any dynamic business data. Each resource is identified by URIs/ global IDs. REST can use various representation to represent a resource like text, JSON, XML. Though in Spring Boot Microservices applications, JSON is the most popular one used.

RESTful web services developed by applying REST architectural concept.

RestTemplate is the core class for accessing Spring RESTful web services from the client-side. It communicates via HTTP server using RESTful constraints.

We can build RESTful web service in Spring Boot by adding ‘spring-boot-starter-web’ starter pack in the classpath. We can then create a controller class to define all API (URL) and REST operations like GET, POST, etc. This class should be annotated with @RestController, making the class return the object. In case we want to convert the response to JSON format then we need to add Jackson to the classpath. Along with Spring Boot’s embedded Tomcat server, we can have the REST server running via the application Jar.

HATEOAS (Hypermedia as the Engine of Application State) is a principle for REST APIs, according to which the API should guide the client through the application by returning relevant information about potential subsequent steps, along with the response.

This information is in the form of hypermedia links included with responses, which helps the client to navigate the site's REST interfaces. It essentially tells the clients what they can do next, and what is the URI of the resource. If a service consumer can use the links from the response to perform transactions, then it would not need to hardcode all links.

According to the Richardson Maturity Model, HATEOAS is considered the final level of REST.

To support HATEOAS, each resource in the application should contain a "links" property which defines hyperlinks to related resources. 

Each link object typically includes the following properties:

"rel”: Relation with the target resource.

"href”: URI for resource

For example:

{
 "contractId": 10067,
 "description": "Contract details for the requested orderId",
 "status": "created",
 "links": [
 {
"rel": "self",
    "href": "http://demoApplication.com/contracts/10067"}]
 }

Traditional Spring controllers are created by adding a class with @Controller annotation. It is actually a specialization of the @Component annotation that allows the implementation classes to be autodetected by Spring context through the classpath scanning.

Generally, @Controller annotation is used in combination with @RequestMapping and @ResponseBody added to the request handling methods to define the REST APIs.

@RestController is a convenient annotation that combines both the features of @Controller and @ResponseBody annotations.

The key difference between typical Spring @Controller and the RESTful web service @RestController is the way the HTTP response body is created. While the traditional MVC controller relies on the View technology, the RESTful web service controller returns the object and the object data is written directly to the HTTP response as JSON.

@Autowired annotation is used to autowire i.e. inject dependent bean on the constructor, setter method or a field/property. When @Autowired is used on dependency, the application context searches for a matching dependency and provides as required. This helps us to avoid writing explicit injection logic.

However, by default, all dependencies that are Autowired are required. So, in scenarios where a required dependency is not available or if there is conflict; it results in an exception like NoUniqueBeanDefinitionException.

There are a few options available to turn off the default behavior:

  1. By using (required=false) option with @Autowired to make it non-mandatory for a specific bean property.

@Autowired (required=false)

private Contract contractBean;

  1. By using @Qualifier, we can further qualify autowiring; in scenarios when two beans are created with the same name.

@Qualifier ("design")

private Contract contractBean;

Microservices (MS) is an architecture pattern that prescribes to divide an application based on business functionality instead of technical boundaries.  These set of smaller interconnected services constitute the complete application. As opposed to monolithic architecture, it recommends breaking the application into smaller atomic units, each performing a single function.

Typically, an application provides a set of distinct features or functionality, such as order management, billing, customer service, etc. Each microservice works as a mini-application that has its own hexagonal architecture. It is often compared to Honeycombs (nests) that are a combination of multiple hexagonal structures.

Below are some of the key features of Microservices that distinguish from monolithic:

  1. Tight Cohesion: Single responsibility per service i.e. code perform a single and well-defined task only.
  2. Loose Coupling: Microservices are the autonomous i.e. effect of changes are isolated to that particular MS only.
  3. Interoperability: One of the key foci of microservices is on communication between systems using diverse technologies.
  4. Stateless: An ideal microservice does not have a state i.e. it does not store any information between requests. All the information needed to create a response is present in the request.
  5. Devops: It is highly recommended to implement an automated build and release process using suitable CI-CD infrastructure.
  6. Developing Products instead of Projects.

Spring Cloud Contract implements the Consumer Driven Contracts (CDC) approach via the 'Spring Cloud Contract Verifier' project.

Consumer Driven Contracts is a software development and evolution approach where each consumer of service develops a contract that contains the consumer's expectations about the APIs provided by Service. The full collection of all of the consumers' contracts constitutes the requirement set for the service.

Once the service owners have all of the contracts for their consumers, the service owners can develop a test suite that verifies the service APIs. This test suite provides rapid feedback about failures when the service changes.

In Spring Cloud Contract, a "producer" is the owner of an API and a "consumer" is the user of an API.

Service A (as a consumer) creates a contract that service B (as a producer) will have to abide by. This contract acts as the invisible glue between services - even though they live in separate code bases and run on different JVMs. Breaking changes can be detected immediately during build time.

Netflix’s Hystrix is a library that provides an implementation of the Circuit Breaker pattern for Microservices based applications. A circuit breaker is a pattern that monitors for failures and once the failures reach a certain threshold, the circuit breaker trips, and all further calls will return with an error, without the external call being made at all.

On applying Hystrix circuit breaker to a method, it watches for failing calls to that method, and if failures build up to a threshold; Hystrix opens the circuit so that subsequent calls automatically fail.

While the circuit is open, Hystrix redirects call to a specified method called a fallback method. This creates a time buffer for the related service to recover from its failing state.

Below are the annotations used to enable Hystrix in a Spring Boot application:

@EnableCircuitBreaker: It is added to the main Application class for enabling Hystrix as a circuit breaker and to enable hystrix-javanica; which is a wrapper around native Hystrix required for using the annotations.

@HystrixCommand: This is method annotation that notifies Spring to wrap a particular method in a proxy connected to a circuit breaker so that Hystrix can monitor it. We also need to define a fallback method having the backup logic that needs to be executed in the failure scenario. Hystrix passes the control to this fallback method when the circuit is broken.

This annotation can also be used for asynchronous requests. Currently, it works only with classes marked with @Component or @Service.

In a typical Microservice architecture multiple services collaborate to provide an overall functionality. These set of service instances may have dynamically assigned network locations. Also, the services scale up and down as per the load. It could get tricky in a cloud environment resolving the services that are required for operation for common functionality.

Consequently, in order for a client to make a request to a service, it must use a service-discovery mechanism. It is the process where services register with a central registry and other services query this registry for resolving dependencies.

A service registry is a highly available and up to date database containing the network locations of service instances. The two main service-discovery components are client-side discovery and service-side discovery.

Netflix Eureka is one of the popular Service Discovery Server and Client tools. Spring Cloud supports several annotations for enabling service discovery.  @EnableDiscoveryClient annotation allows the applications to query Discovery server to find required services.

In Kubernetes environments, service discovery is built-in, and it performs service instance registration and deregistration.

Traditional monolithic applications developed in the last few decades had the luxury of considerable response time, multiple hours of offline maintenance and smaller volumes of data. However, this is not acceptable with the modern applications serving high volumes round the clock with an expectation of sub-second response time with 100% availability.

Reactive programming is one of the solutions for the above constraints, which is rapidly gaining popularity in cloud-based applications. It is a programming pattern that recommends an asynchronous, non-blocking, event-driven approach for data processing. In the reactive style of programming, after making a request for the resource, the application continues to perform other tasks instead of waiting for the response. When the data is available, the application should get the notification along with data in the form of call back function which handles the response as per business needs.

Systems built as Reactive Systems are highly flexible, loosely coupled, and scalable. This makes them easier to develop and responsive to change. They are significantly more resilient and are able to handle failures gracefully. They are quite responsive and ideal for interactive applications.

Spring Web Reactive brings reactive capabilities for web applications, which is based on the same fundamental programming model as Spring MVC. The base API is 'Reactive HTTP' as opposed to 'Servlet API' and runs only on Servlet Containers like Netty or Undertow.

We need to add 'spring-boot-starter-webflux' to enable Spring Reactive and 'spring-boot-starter-reactor-netty' as the default embedded reactive server; in the application dependencies.

Creating a Spring Reactive Controller is similar to a typical Spring MVC Controller using @RestController and the required @RequestMapping annotations.

Cloud Foundry is an open source cloud PaaS (platform as a service) where developers and organizations can build, deploy, run and scale their applications. It is the same company that manages Spring, hence has great support for running Spring based cloud applications.

For deploying an application in Cloud Foundry, we need to configure the application with a target and a space to deploy the application to.

It is increasingly gaining popularity as an open source and lets us use our own tools and code. Organizations can deploy Cloud Foundry PaaS on their own internal infrastructure; on cloud providers' infrastructure, such as Amazon Web Services (AWS) or Microsoft Azure.

It also provides a few out of the box components:

  1. Authentication: Contains an OAuth2 server and login server for user identity management.
  2. Application Lifecycle: Provides application deployment and management services.
  3. Application Storage and Execution: It can control when an application starts and stops, as well as the VM's containers.
  4. Service Brokers: Helps connecting applications to services like databases.
  5. Messaging: Enables VMs to communicate via HTTP or HTTPS protocols, can also store data like application status.
  6. Metrics and Logging. It provides Loggregator tool, which helps organizations monitor their Cloud Foundry environment.

It is very easy to set up and application on Cloud Foundry:

  1. Create a pivotal Cloud Foundry account.
  2. Create an organization and space to deploy the application.
  3. Add the plugin with the configuration of Cloud Foundry org and space in application pom.xml/build.gradle.

Popular logging frameworks such as Log4j, Logback, and SLF4J, etc. provide logging functionality for the individual microservice application. However, when a group of run together to provide complete business functionality, it becomes really challenging to trace a request across all the services, especially in case of failures.

Hence it is highly recommended to have a centralized logging solution in place, to have all the log messages stored in a central location rather than on local machine/container of each microservice. This eliminates dependency on the local disk space (volumes) and can help retain the logs for a long time for analysis in the future.

The Elasticsearch, Logstash, and Kibana tools, collectively known as the ELK stack, provide an end-to-end logging solution in the distributed application; providing a centralized logging solution. ELK stack is one of the most commonly used architectures for custom logging management in cloud-based Microservices applications.

Elasticsearch is a NoSQL database used to store the logs as documents. Logstash is a log pipeline tool that accepts logs as input from various micro service applications, executes transformations if required and stores data into the target (Elasticsearch database).

Kibana is a UI that works on top of Elasticsearch, providing a visual representation of the logs and ability to search them as required.  All three tools are typically installed on a single server, known as the ELK server.

In a centralized logging approach, applications should follow a standard for log messages. Each log message having a context, message, and correlation ID. The context information is ideally can be the IP address, user information, process details, timestamp, etc. The message is a simple text description of the scenario. The correlation ID is dynamically generated and is common across all that used for end-to-end tracking of a request/task.

Description

Spring Boot is one of the most popular Java EE frameworks for web applications. It is a project which is built on the Spring Framework. It helps to run both, simple and web-based applications in a simpler and faster manner. Both Aspect Oriented Programming and  Dependency Injection are at the heart of the spring framework. In recent times, the demand for Spring Boot developers has increased exponentially. Therefore your chances of getting hired as a Spring Boot expert are really high only if you are thorough with the critical concepts in Spring Boot.

Candidates can opt for the posts of Backend Developer, Java Developer, Java Architect, etc. According to Neuvoo.com, the average salary that a professional is offered in this field is $125,000 per year.

Every interviewer is different and their questions may vary as well. By preparing these spring boot tough interview questions, you can leave a great impression during your next job interview. In order to answer spring boot questions with confidence, you should also have in-depth knowledge of some of its core features like stater dependencies and auto-configuration.

These top interview questions and answers on Spring Boot take you through the basics of Spring boot, its features, working, interceptors and how to implement them.

Stretch your knowledge with the proven tips to clear Spring Boot interviews. Our expert-designed Spring Boot interview questions will be your best guide in preparing for Spring Boot interviews. These interview questions will enable you to face the toughest of interviews confidently.

These Spring Boot interview questions are good for experienced programmers as well as for the people who are new to Spring Boot framework. Prepare better these spring boot microservices interview questions which are normally asked in spring boot advanced interview which will give you a head start.

Bookmark this page and start your preparation with these Spring Boot interview questions. All the best!

Read More
Levels