Spring Interview Questions

Prepare with the top Spring Interview Questions given here. These have been answered by experts and will be your best guide to surviving the trickiest Spring Developer interviews. Convert your next Spring Developer interview into a sure job offer as a Java Spring Developer. These Spring framework interview questions and answers are based on real-time projects and will help you answer the questions like Dependency Injection, ways to create spring bean thread-safe, design patterns used in Spring framework, Loose Coupling, Component Scan, etc.

  • 4.5 Rating
  • 22 Question(s)
  • 20 Mins of Read
  • 6987 Reader(s)

Intermediate

Inversion of control is a software engineering principle that transfers control of objects or parts of a program to a container or framework. In object-oriented programming, it is most often used. In contrast to traditional programming, where our custom code calls to a library, IoC allows a framework to control a program's flow and make calls to our custom code. Frameworks use abstractions with other built-in behaviours to enable this. If we want to add our own behaviour, we must extend the framework classes or add our own classes.

The benefits of this architecture are:

  • Decoupling the implementation of the task
  • It makes switching between different implementations easier
  • Increased program modularity
  • It is easier to test a program by isolating a component or mocking its dependencies and enabling components to communicate via contracts

Various mechanisms such as Strategy design, service locator pattern, factory pattern and dependency injection (DI) can be used to implement IOC.

When developing Spring Boot applications, tell the Spring Framework where to look for Spring components. A Component scan is one way for Spring to detect managed components from Spring. When the application starts, Spring needs the information to locate and register all Spring components in the application context. Spring can scan, detect and instantiate components from predefined project packages automatically.

Spring can automatically scan all classes with stereotypes @Component, @Controller, @Service and @Repository

For example

import org.springframework.stereotype.Component;

@Component("demoBeanA")
public class DemoBeanA {
}

The @Primary annotation is used in the spring framework to give a bean a higher preference if there are several beans of the same type.

The @Primary annotation can be used directly or indirectly with @Component or with @Bean annotated methods for any class.

The following examples show the use of an annotation @Primary. Consider the Car interface below.

public interface Car {
public void run();
}

Create two beans that implement the user interface named FastCar and SlowCar.

public class FastCar implements Car {

@Override
public void run() {
System.out.println("Inside run() method of FastCar");
}

}

public class SlowCar implements Car {
@Override
public void run() {
System.out.println("Inside run() method of SlowCar");
}
}

In java - based configuration class, declare the FastCar and SlowCar beans.

@Configuration
public class AppConfig {
@Bean
@Primary
public User getFastCar() {
return new FastCar();
}

@Bean
public User getSlowCar() {
return new SlowCar();
}
}

Now create the main class and run the application.

public class MainApp {
public static void main(String[] args) { AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
 Car car=context.getBean(Car.class);
car.run();
context.close();
}
}

Output:

Inside run() method of FastCar

From the above output, it is clear that the getFastCar() (method, which is annotated with @Primary, is first autowired.

When we create more than one bean of the same type and we want to wire only one of them with a property, in that case, we can use @Qualifier with @autowired. Here is an example of the same.

public class UserProfile{
  @Autowired
  @Qualifier("firstUser")
  private User user;

  public UserProfile(){
     System.out.println("Hi" );
  }
  public void printAge() {
     System.out.println("Age of the user: " + user.getAge() );
  }
  public void printName() {
     System.out.println("Name of the user: " + user.getName() );
  }
}

In order to render models in the browser without binding the implementing to specific view of technology.

View Resolver maps the name of the view to actual views. Spring framework comes with the number of view solvers.

  • InternalResourceViewResolver
  • XmlViewResolver

and a few others.

@EnableWebMvc

@Configuration
@ComponentScan("org.baeldung.web")

public class WebConfig implements WebMvcConfigurer 
      { // All web configuration will go here
@Bean
public ViewResolver internalResourceViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/view/");
bean.setSuffix(".jsp");
return bean;
}
}

The @ModelAttribute annotation is one of the most important Spring - MVC annotations.

The @ModelAttribute is an annotation that links a method parameter or method return value to the attribute named model and then exposes it to a web view.

At the Method Level

The purpose of this method is to add one or more model attributes when the annotation is used at the method level. Such methods support the same types of arguments as @RequestMapping, but cannot be mapped directly to requests.

@RequestMapping(value = "/addUser", method = RequestMethod.POST) 
public String submit(@ModelAttribute("user") User user) {
// Code that uses the user object

return "userView";
}

It binds the data of the form to a bean. The controller annotated with @RequestMapping can be annotated with @ModelAttribute by custom class argument(s). This is commonly referred to as data binding in Spring - MVC, a common mechanism that saves you from individually analyzing each form field.

Many Spring Boot developers like their apps to use auto-configuration, scan components and define the additional configuration in their "app class." A single @SpringBootApplication annotation can be used to enable these three functions, i.e.

  • @EnableAutoConfiguration: Enable the auto-configuration mechanism of Spring Boot
  • @ComponentScan: Enable @Component scan in the package where the application is located (see best practices)
  • @Configuration: Enable the registration of additional beans in the context or import additional configuration classes.

Advanced

The act of wiring beans together is based on a pattern known as dependency injection (DI). Rather than have components create and maintain the lifecycle of other beans that they depend on, a dependency-injected application relies on a separate entity (the container) to create and maintain all components and inject those into the beans that need them. This is done typically through constructor arguments or property accessor methods.

As per shown in the example, you can inject any email service provider and it can send an email at runtime provided the injecting class follows a valid contract.

package com.knowledgehut.java;

public class MyApp {
   private EmailServiceProvider emailProcessor = null;
   public MyApp(EmailServiceProvider service){
   this.emailProcessor=service;
   }
   public void sendEmail(String message, String toEmail ){
   this.emailProcessor.sendEmail(msg, toEmail);
   }
}

Some of the benefits of using Dependency Injection are Separation of Concerns, Boilerplate Code reduction, Configurable components, and easy unit testing.

IOC: Inversion of control is used when you are not worried about the actual creation of objects. You will assume that the object will be created and it will be supplied to the executor while execution. Inversion of Control is a principle in software engineering by which the control of objects or portions of a program is transferred to a container or framework. It’s most often used in the context of object-oriented programming. IOC can be implemented using service locators, events, delegates or dependency injection.

Dependency Injection is a form of IOC. Dependency injection can be achieved via constructor injection, property injection or even a method injection. DI provides a way to inject objects into other objects. 

For example,

public class Customer{
public Logger log;
public Customer(Logger obj){      // this is constructor injection
log = obj;
}
}

Three Annotation-Based Injection Patterns

  • Field injection
import org.springframework.beans.factory.annotation.Autowired; 
public class MyClass {
@Autowired
private OtherClass otherClass ;
//Business logic...
}
  • Setter injection
import org.springframework.beans.factory.annotation.Autowired; 
public class MyClass {
private OtherClass otherClass ;
@Autowired
    public void setOtherClass(final OtherClass otherClass) {
        this.otherClass = otherClass ;
}
//Business logic...
}
  • Constructor injection
public class MyClass {
private final OtherClass anotherBean;
public MyClass(final OtherClass otherClass) {
this.otherClass = otherClass;
}
//Business logic...
}

Constructor Injection is better than other patterns from all other patterns

It is advisable to utilize constructor injection for every mandatory collaborator and setter injection for every single other property. Once more, constructor injection guarantees every required property have been fulfilled, and it is essentially impractical to instantiate an object in an invalid state (not having passed its collaborators). When utilizing constructor injection you don't need to utilize a dedicated mechanism to guarantee required properties are set (other than typical Java mechanism).

In case if we are using field injection which is non-final, they are prone to circular dependencies. Though it exposes coupling if there are more than 3 objects as part of the constructor injection. It is also easy to test if we use constructor injection.

  • Singleton: Spring creates only the single instance of the bean and returns the same (cached) on any number of requests from the container for the object. In case of any changes in the bean, all reference of the bean will be changed. This is the default scope in spring framework.
  • Prototype:If bean’s scope is defined as a prototype, then the spring container provides a new instance every time on the request.
  • Request(web aware): Each Http request has its own instance and valid only for web aware spring application context.
  • Session(web aware): Spring container return the same bean if the request is from the same session.
  • Global-session: This scope is similar to session scope. It applies only in the context of the portlet-based web application.
  • Create immutable beans
    • Immutable class means that once an object is created, we cannot change its content. In Java, all the wrapper classes (like String, Boolean, Byte, Short) and String class are immutable. We can create our own immutable class as well.
//     An immutable class 
public final class Student

{
final String name; 
    final int regNo;

public Student(String name, int regNo)
{
this.name = name;
this.regNo = regNo;
}
public String getName()
{
return name;
}
public int getRegNo()
{
return regNo;
}
}
  • Create stateless beans
    • A Stateless object is a special instance of the class without the instance variables. All fields are static final. You can say it is immutable. It may have a state but it does not change. These kind of instances are by default thread-safe.
class Stateless
{
//No static modifier because we're talking about the object itself
final String TEST = "Test!";
void test() {
System.out.println(TEST);
}
}
  • Design persistent beans - a special case of immutable.

Design patterns help to follow good practices of programming. Spring framework, as one of the most popular web frameworks, also uses some of them.

The proxy pattern is used heavily in AOP and remoting.

Spring class “org.springframework.aop.framework.ProxyFactoryBean” uses a proxy design pattern. It builds the AOP proxy based on Spring beans.

The proxy provides a placeholder for another bean to control access to it.

In the Singleton design pattern, only a single instance of the class is returned on any number of request to create an object of the class. In the spring framework, the Singleton is the default scope and the spring container creates and returns an exactly single instance of the class per spring container. Spring container cache the singleton bean and return the same bean upon any request for the bean. It is recommended to use the singleton scope for stateless beans.

Factory design pattern

It provides a public static factory method to initialize the object.

The Spring framework uses the factory design pattern to create the bean using BeanFactory Container and ApplicationContext Container.

Template Design Pattern

The pattern used heavily to reduce boilerplate code. For example JdbcTemplate, JmsTemplate, JpaTemplate.

Model View Controller Pattern

Spring MVC is using the pattern in the web application. The controller is POJO instead of servlet, which makes controller testing easier. The controller returns logical view name and responsibility to resolve the view is on ViewResolver, which makes it easier to reuse controller for different view technologies.

Front Controller Pattern

Spring dispatcherservlet dispatches all incoming request to the mapped controller. It helps to implement all cross-cutting concerns or tracking request and response.

Dependency injection or inversion of control (IOC)

The spring framework is responsible for the creation, writing, configuring object and manage the entire lifecycle of these objects until they are completely destroyed. The container has the Dependency Injection (DI) responsible to manage the components present in an application.

HATEOAS?

The HATEOAS is the principle in which the API helps the client using the application by returning relevant information about the next possible steps together with a response.

The specific style of formats helps the client to navigate the resource dynamically by traversing the hypermedia links, which is the same as the user clicks the appropriate hyperlink to achieve a final goal.

{
"
                                                 "departmentName": 
             "Administration",
                                 "locationId": 1700,
                               "managerId": 200,
"links": [

{

                                              "rel": "employees",
                                      "type" : "GET"
}
 
]
}

To add special character in it, add a regex mapping {q:.+} in @RequestMapping

@RequestMapping("/site")
public class SiteController {

@RequestMapping(value = "/{q:.+}", method = RequestMethod.GET) 
       public ModelAndView display(@PathVariable("q") String q) {

logger.debug("Site : q : {}", q);
return getModelAndView(q, "site");

}
//...

Now, for input /site/google.com, “q” will display the correct google

A Dependency Management, inherited from the spring-boot-dependencies pom, that manages the versions of common dependencies. This dependency management lets you omit <version> tags for those dependencies when used in your own pom. Execution of the repackage goal with a repackage execution id.

All of the dependent jar files or library files are managed by spring boot version. Once you specify spring boot version, you do not need to manage versions of other dependent libraries. It also helps to manage multi-module projects.

It also avoids conflicting versions of jar files and maintains a single version which is compatible with other dependencies as well.

In addition to the CrudRepository, there is a PagingAndSortingRepository that adds additional methods to ease paginated access to entities:

public interface PagingAndSortingRepository<T, ID extends 
Serializable> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}

Accessing the third page of Userby a page size of 10 you could simply do something like this

PagingAndSortingRepository<User, Long> repository = // ... get access to a bean 
   Page<User> users = repository.findAll(new PageRequest(2, 10));

When you are working for a new application, it becomes important to work on standard best practices which are going to be reusable by all developers. Some of the aspects which can be considered as cross-cutting concerns are auditing, logging, security, transactions, versioning, etc.

AOP is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It does so by adding additional behaviour to existing code without modification of the code itself.

Instead, we can declare this new code and these new behaviours separately.

Spring’s AOP  framework helps us implement these cross-cutting concerns.

Most applications use properties as factors or parameters that have been extricated from the primary rationale and infused into the application at runtime. Customarily, these properties existed in records sent to the server.

The profile feature of Spring boot allows developers to group related properties with their values into a properties file, subsequently allowing deployment scripts to refer to the logical grouping of properties with a single environment variable reference at runtime, which simplifies the application.

Spring Profiles give an approach to isolate parts of your application design and influence it to be available only in certain environments.

Think about Spring AOP and AspectJ over various pivot – for example, capabilities, goals, weaving, internal structure, joinpoints, and simplicity.

Capabilities and Goals

Spring AOP means to give a basic AOP execution crosswise over Spring IoC to take care of the most widely recognized issues that software engineers face. It isn't proposed as a total AOP arrangement – it can only be applied to beans that are managed by a Spring container.

Then again, AspectJ is the original AOP technology which means to give complete AOP solution. It is more robust yet in addition altogether more complicated than Spring AOP. It's additionally important that AspectJ can be connected over all the domain objects

Weaving

Both AspectJ and Spring AOP utilizes the diverse kinds of weaving which influence their behaviour in regards to execution and convenience. AspectJ makes use of three different types of weaving:

  1. Compile-time weaving: The AspectJ compiler takes as info both the source code of our aspect and our application and produces a woven class file as yield
  2. Post-compile weaving: This is otherwise called binary weaving. It is utilized to weave existing class files and JAR files with our aspects
  3. Load-time weaving: This is actually similar to the previous binary weaving, with a distinction that weaving is deferred until a class loader loads the class files to the JVM
  4. As AspectJ utilizes compile time and classload time weaving, Spring AOP makes utilization of runtime weaving.

With runtime weaving, the aspects are woven amid the execution of the application utilizing proxies of the targeted object – utilizing either JDK dynamic proxy or a CGLIB proxy

Swagger is an open-source software framework supported by a large tool ecosystem that helps developers design, build, document and use RESTful web services. While most users use the Swagger UI tool to identify Swagger, the Swagger toolkit includes support for automated documentation, code generation and testing.

We use annotation @EnableSwagger2 to enable Swagger 2. A docket bean is defined and we get an instance of ApiSelectorBuilder using the select () method. ApiSelectorBuilder we set the Swagger exposed endpoints. After the Docket bean is defined, the select () method returns an instance of ApiSelectorBuilder, which provides a way to control the Swagger exposed endpoints. We configure RequestHandlerSelectors and PathSelectors to select RequestHandlers.

Steps to add swagger in spring boot.

1)  Add swagger dependency

<dependency>
<groupId>io.springfox</groupId>

<artifactId>springfox-swagger2</artifactId> 
       <version>2.9.2</version>
</dependency>

2) Add swagger configuration in spring class.

@Configuration

@EnableSwagger2

public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}

3) To enable Enabling Springfox’s Swagger UI, add this dependency

<dependency>
<groupId>io.springfox</groupId>

<artifactId>springfox-swagger-ui</artifactId>   
     <version>2.9.2</version>
</dependency>
Levels