Popular Questions on Spring Boot

Salitha Chathuranga
11 min readAug 3, 2022

Let’s learn how to answer properly…

Today I brought you very popular 20 questions that are frequently asked in Spring Boot technical interviews. So, read the questions and answers and get ready for interviews!!!

1. What are the features of Spring Boot?

Spring Boot is an extension of Spring, which eliminates the boilerplate configurations required for setting up a Spring application.

  • Auto Configuration

This is the most important feature of Spring Boot. This removes manual configuration in a huge margin. There’s a library inbuilt called auto-configure coming with the base framework, which does the job for us. It detects the presence of certain classes and on the class path and configures them automatically for us.

Ex:
— When we add the spring-boot-starter-web dependency in the project, Spring Boot auto-configuration looks for the Spring MVC is on the classpath. It auto-configures dispatcherServlet, a default error page, and web jars.
— Similarly, when we add the spring-boot-starter-data-jpa dependency, we see that Spring Boot Auto-configuration, auto-configures a datasource and an Entity Manager.

  • Embedded Tomcat web server

Spring Boot is shipped with Tomcat server by default. So, we do not need to configure a server to run the application(if our preferred server is Tomcat).

  • Starter POMs

There are lot of starter POMs to achieve most common tasks in developing life, provided by Spring Boot itself. We can depend on them and the framework itself and don’t need to go for a 3rd party library. I have listed some of them here.

spring-boot-starter-web: To create REST APIs
spring-boot-starter-data-jpa: To connect to SQL databases
spring-boot-starter-data-mongodb: To connect to MongoDB
spring-boot-starter-aop: To apply Aspect Oriented Programming concepts
spring-boot-starter-security: Implement security like Role based auth
spring-boot-starter-test: To implement unit tests

  • Actuator APIs

Spring Boot Actuator is a sub-project of the Spring Boot framework. It enables us to viewing insights and metric and monitoring the running application through a set of API endpoints. We don’t need to manually create them.

Example usages of Actuator
— Database stats: data source usages
— CPU Memory usages
— GC cycles
— Trace HTTP requests

  • Spring Initializer

This comes as a web based UI mainly which provides the ability to create a new Spring Boot project using dependencies available and download the project created as a zip. So we don’t have to create it from scratch. All the basic structure of the project is already there in this downloaded zip. Spring Initializer comes as IDE plugins also with different names. Ex: For IntelliJ — plugin is Spring Assistant or Spring Initializer.

2. Do you know how “@SpringBootApplication” annotation works internally?

Spring Boot application is executed using this annotation. Actually it’s a combination of 3 other annotations: ComponentScan, EnableAutoConfiguration and Configuration.

@SpringBootApplication =
@ComponentScan + @EnableAutoConfiguration + @Configuration

“@Configuration” — All annotated classes are considered ad configurations for Spring Boot and they are eligible to create beans and return to the IOC container.

“@ComponentScan” — All annotated classes will be scanned through packages(where to look for) and helps the process of creating instances of those classes.

“@EnableAutoConfiguration” — This is the magical annotation. This looks for the class-paths. There’s a library inbuilt called auto-configure coming with the base framework, which does the job for us. It detects the presence of certain classes and on the class path and configures them automatically for us. I have put a snapshot of the library below. If you head over to spring.factories file, you will see the available class configurations.

auto-configure dependency JAR

Let’s say we have added JPA dependency. Spring Boot checks for class-path to see what is available and what are the properties defined in application.properties/yml file. Here it will be database URL and credentials. JPA Repository classes are also annotated with some Conditional Annotations like “@ConditionalOnBean”, “@ConditionalOnClass”. According to those rules, configurations are generated.

3. What is a Bean?

Beans are just Plain Java objects. In Spring Boot context they are considered as Java objects + Objects that are initializing automatically when the application is starting up and managed by the Spring IOC container. We have “@Bean” annotation to achieve this.

4. What is Inversion of Control(IOC) in Spring?

Inversion of Control:

The principle which transfers the control of objects or portions of a program to a container or framework. We most often use it in the context of object-oriented programming. Simply, control is taken care by the framework, not by us— Inverse of control flow of the program.

Spring IOC container:

The Container which creates the objects, configures and assembles their dependencies, manages their entire life cycle. It uses Dependency Injection(DI) to manage the components that make up the application.

5. How to we achieve dependency injection in Spring Boot?

DI — passing object as a dependency to another objects

In Spring Boot we can achieve this using “@Autowired” annotation. Then Spring IOC container will take care of creating the objects on behalf of us. Usually, in Controller layer we inject Services and in Service layer we inject Repositories to using this annotation.

6. What are the layers in Spring Boot micro service?

Controller Layer:
All the controllers which are having the API endpoint definition methods. Classes are annotated with “@RestController” annotation.

Repository/DAO Layer:
All the repository interfaces are included in this layer which are used to query the database which has been selected(SQL/no SQL). Interfaces are annotated with “@Repository” annotation.

Service Layer:
All the business logic is included here. Normally DAO layer is accessed in this layer to perform some operations. Classes are annotated with “@Service” annotation.

Entity Layer:
All the classes which are mapped to the real world are included in this layer. Normally all ORM related annotations are put in these classes.
— If it’s connected with MySQL, we annotate with “@Entity” with table name.
— If it’s connected to MongoDB, we annotate with “@Document” with collection name.

Additionally we can use libraries like Lombok to define getters and setters here.

7. What is the difference between “@Controller” and “@RestController” annotations?

Source: GeeksForGeeks

More info: https://www.geeksforgeeks.org/difference-between-controller-and-restcontroller-annotation-in-spring/

8. What are Spring profiles?

Spring framework provides the ability to group configuration properties into profiles, allowing us to activate them depending on the environment we deploy. Simply profile means a set of grouped configurations.

More Info: https://medium.com/@salithachathuranga94/spring-boot-profiles-6f8b841cf11c

9. How to connect to a database using Spring Boot?

Usually we don’t need to create singleton database classes, connection pooling methods and any other implementations. Spring Boot Auto Configuration will do all those classes and config setup for us. Just need the setup only.

  1. Add starter dependency for the database(MySQL/MongoDB/Redis) to the POM.
  2. Define configs in application.properties/yml file — Ex: Database URL and credentials

10. How to write a custom query in DAO layer?

Usually in Repository layer, we extend the interface with JPARepository or MongoRepository interface. After that, our Repository(DAO) will have all the methods available in Spring Boot Repository interfaces. Es: save(), saveAll(), findById(), find() and etc.

But there may be situations where we need some other methods also according to our business requirement.

Ex: findByEmail(), findUsersByRegion() and etc…singleton

So, we have to provide a custom query in this kind of cases. There we have “@Query” annotation to achieve this. Simply we have to define the query just before each method definition. That’s all!

If we are using JPA, we have to create query using JPQL(Java Persistence Query Language). It is defined in the JPA specification and is an object-oriented query language used to perform database operations on persistent entities.

Ex: Find users in a given region only

@Query("select u from users u where u.region =: region")
Optional<List<User>> findUsersByRegion(String region);

11. How to handle transactions in Spring Boot? Any annotations used?

Spring Boot provides an annotation called “@Transactional” to manage transactions.

Let’s assume a product ordering scenario. We need to process order in Order Service and send the payment details to Payment Service via a REST call. Imagine a suddenly the payment service came down. If the order details were persisted in its own database just before sending API call to payment service, then there will be discrepancies in future since payment service data is loosing that record!

To avoid this, we can put “@Transactional” annotation into the method in Order Service. Then from there on wards, if something failed when calling to Payment Service, all data in the ongoing flow is rolled back!

@Transactional
public Order orderProduct(Product product, Double payment) {
// process order
// send REST call to payment service
}

12. Where we need to use “@Qualifier” annotation?

This annotation is used to tell Spring Boot specifically to pick up a specific class from all its available implementation beans. @Qualifier annotation is used along with “@Autowired” annotation for dependency injection.

Let’s say we have 1 Interface and 2 different implementation classes.

Ex: UserService Interface => AdminUserService, StaffUserService classes

Both AdminUserService, StaffUserService are implementing the UserService interface. We have to choose StaffUserService when service is started. Otherwise Spring Boot will throw and exception complaining there are too many candidates. See the error below…

Description:Field userService in com.example.demo.UserExecutor required a single bean, but 2 were found:
- adminUserService: defined in file [/home/salitha/Downloads/demo/target/classes/com/example/demo/AdminUserService.class]
- staffUserService: defined in file [/home/salitha/Downloads/demo/target/classes/com/example/demo/StaffUserService.class]
Action:Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

So we should put Qualifier annotation after Autowired to fix this issue.

@Autowired
@Qualifier("staffUserService")
private UserService userService;

Example Java class setup to test this.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

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

interface UserService {
void login();
}

@Service
class AdminUserService implements UserService {
@Override
public void login() {
System.out.println("Admin Login");
}
}

@Service
class StaffUserService implements UserService {
@Override
public void login() {
System.out.println("Staff Login");
}
}

@Configuration
@ComponentScan("com.example.demo")
class AppConfig {
@Autowired
UserExecutor userExecutor;


@PostConstruct
void testBeans() {
userExecutor.getLogin();
}
}

@Component
class UserExecutor {
@Autowired
@Qualifier("staffUserService")
private UserService userService;
public void getLogin() {
userService.login();
}

}

13. Can we replace Tomcat server in a Spring Boot project? How?

Yes. If we want, we can remove Tomcat server by adding maven exclusion into the POM. Actually web server is bundled in started-web Spring Boot starter dependency. Exclusion should be added to that.

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

Then we have to add any other server like Jetty to the POM. Anyway we have to add a web server after removing tomcat.

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

You will see the Jetty server log now, instead of Tomcat.

2022-08-03 13:22:12.551  INFO 57495 --- [           main] o.s.b.web.embedded.jetty.JettyWebServer  : Jetty started on port(s) 8080 (http/1.1) with context path '/'

14. What is the difference between “@PathVariable” and “@RequestParam”?

PathVariable — This is used when we setup API endpoint with parameters separating with “/”.

@GetMapping(path = "/profile/{username}")
public ResponseEntity<?> getUser(@PathVariable("username") String username) {
return ResponseEntity.ok().body(authService.findUserByUsername(username));
}

API endpoint: http://localhost/api/profile/salitha

RequestParam— This is used when we setup API endpoint with query parameters separating with “&” and starting with “?”.

@GetMapping(path = "/confirm")
public ResponseEntity<?> confirmUser(@RequestParam("token") String token) {
return ResponseEntity.ok().body(authService.confirmUser(token));
}

API endpoint: http://localhost/api/profile?token=12345678

15. What is the usage of “@Primary” annotation?

@Primary indicates that a bean should be given preference when multiple candidates are qualified to auto-wire a single-valued dependency.

16. How to communicate between two micro service?

  • Here we have RestTemplate class to communicate between services using REST calls. In already has methods to perform GET/POST operations by giving API endpoints and parameters or request body.

More Info: https://medium.com/@salithachathuranga94/rest-template-with-spring-boot-e2001a8219e6

  • We can either use messaging channels like Kafka to distribute some messages via publisher subscriber pattern (produce and consume). This is usually used in event driven architectures.

17. How to validate incoming request and inform errors to the user?

There are several main steps to be performed for this. If we follow those, simply requests can be validated.

  1. We have add starter validation dependency into the POM.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2. Add “@Valid” annotation in front of “RequestBody” annotation.

3. Create a separate DTO for the request with validation constraint messages to be shown.

4. Create a Global exception handler using “@RestControllerAdvice” and handle MethodArgumentNotValidException in a separate method.

5. Create the logic to return the errors to the end user as you want. We can extract exception messages inside this logic.es

I have published a detailed guide for this with clear explanations. Follow the below link if needed.

https://medium.com/@salithachathuranga94/validation-and-exception-handling-in-spring-boot-51597b580ffd

18. What is Spring Boot Actuator?

Simply, a sub-project of Spring Boot framework which uses HTTP endpoints to expose operational information about any running application.

Those information includes application metrics, state of databases connected, application state, beans info, request tracing and etc.

It is available as a starter dependency. We can use the library by installing the below dependency.

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

19. How to handle exceptions in Spring Boot micro services?

We can do this in a centralized manner. We need a global configuration class with pre-defined exception handler methods for each exception class. We can define returning HTTP status code also using the handler itself.

  • Create a Global exception handler using “@RestControllerAdvice” and handle Each Exception in separate methods.
  • Create the logic to return the errors to the end user as you want. We can extract exception messages inside this logic
@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, List<String>>> handleValidationErrors(MethodArgumentNotValidException ex) {
List<String> errors = ex.getBindingResult().getFieldErrors()
.stream().map(FieldError::getDefaultMessage).collect(Collectors.toList());
return new ResponseEntity<>(getErrorsMap(errors), new HttpHeaders(), HttpStatus.BAD_REQUEST);
}

@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<Map<String, List<String>>> handleNotFoundException(UserNotFoundException ex) {
List<String> errors = Collections.singletonList(ex.getMessage());
return new ResponseEntity<>(getErrorsMap(errors), new HttpHeaders(), HttpStatus.NOT_FOUND);
}

@ExceptionHandler(Exception.class)
public final ResponseEntity<Map<String, List<String>>> handleGeneralExceptions(Exception ex) {
List<String> errors = Collections.singletonList(ex.getMessage());
return new ResponseEntity<>(getErrorsMap(errors), new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}

@ExceptionHandler(RuntimeException.class)
public final ResponseEntity<Map<String, List<String>>> handleRuntimeExceptions(RuntimeException ex) {
List<String> errors = Collections.singletonList(ex.getMessage());
return new ResponseEntity<>(getErrorsMap(errors), new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}

private Map<String, List<String>> getErrorsMap(List<String> errors) {
Map<String, List<String>> errorResponse = new HashMap<>();
errorResponse.put("errors", errors);
return errorResponse;
}

}

More Info: https://medium.com/@salithachathuranga94/validation-and-exception-handling-in-spring-boot-51597b580ffd

20. What is the difference between “@Entity” and “@Table” annotations?

Entity means the class which you will use in your program and Table means the actual Database table that you will access through your program.

This is all for now guys! It is lengthy already! These are some questions that were asked by me actually, in technical interviews. So, I wanted to share them with you also. I’m pretty sure these answers will clear your path for Spring Boot based questions. If you know these well, you can crack Spring Boot related section in the interviews very easily. 😎 💪 ❤️

Bye Bye!

--

--

Salitha Chathuranga

Senior Software Engineer at Sysco LABS | Senior Java Developer | Blogger