Friday, December 27, 2019

Spring boot Interview Questions for Medium level


Why is Spring Boot suitable for Microservices based cloud applications?
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.

Which Annotation do you use to enable Spring Boot? Elaborate?
@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);
}
}
 
What is an Actuator?
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
How do you implement Exception Handling in Spring Boot?
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 handleGenericContractException(
      final GenericContractException ex) {
LOGGER.error("Generic Contract Exception has occurred.");
    ContractError cerr = ex.createContractError();
return status(gcex.getRespCode()).body(cerr);
  }

Explain the Database/Repository annotations used in Spring?
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.

Can you create a custom Spring Boot starter?
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”.
What is Spring Boot DevTools?
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
What are different ways of running Spring Boot Application?
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 
gradle bootRun

Explain various @Conditional Annotations in Spring Boot.
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() {
    // ...
}

 

Explain the use of Spring Boot Maven plugin?

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. 

spring-boot-maven-plugin
2.1.6.RELEASE

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.

 What is the difference between Spring Boot 1 & Spring Boot 2?

 

  • 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 newAppStore = new ConcurrentHashMap<>();
    @ReadOperation
    public Map 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.

 

How do you go about integrating Spring Boot with Hibernate?

 

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{
}
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 
  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 getAllEmployees()
{
return employeeRepository.findAll();
}
}
 7. Include Spring-boot-web-starter in pom.xml abd Define EmployeeController :
@RestController
@RequestMapping("/employees")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping
public List 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.

 

What does Spring Boot offer with respect to Messaging using ConnectionFactory?

 

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) {
} }

What is AMQP? What does Spring Boot offer with respect to Messaging with AMQP?
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) {
} }

Explain how you go about logging configuration in Spring Boot.
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:
    org.springframework.boot
    spring-boot-starter
    org.springframework.boot
    spring-boot-starter-logging
    org.springframework.boot
    spring-boot-starter-log4j
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

Explain how you will you go about Integration of Swagger with Spring
 Swagger is a set of open-source tools that helps with creating documentation for your REST services.
    springfox-swagger2
    springfox-swagger-ui

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 !!",
                    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.


1 comment: