Core Java

Interview Preparation

last updated on June 24, 2020

Spring and Spring Boot

Spring is a lightweight Java EE application framework used to build applications and framework of frameworks because it provides support to various frameworks such as JSP, Hibernate, etc. Spring framework helps to create loosely coupled applications.

The primary feature of the Spring framework is dependency injection(Dependency Injection (DI) is a design technique that removes dependencies from computer code, making the application easier to maintain and test).
Problems with Spring
Huge Framework
Multiple setup steps
Multiple configuration steps
Boilerplate configurations required for setting up a Spring application
Multiple build and deploy steps

Spring boot makes it easy to create stand-alone,production grade spring based applications that you can "just run". Spring Boot is basically an extension of the Spring framework, which eliminates the boilerplate configurations required for setting up a Spring application. Opinionated ‘starter' dependencies to simplify the build and application configuration Embedded server to avoid complexity in application deployment Metrics, Health check, and externalized configuration Automatic config for Spring functionality – whenever possible Spring Boot provides support for the in-memory database such as H2

The primary feature of the Spring Boot is Autoconfiguration. Spring Boot autoconfiguration is a method of automatically configuring a Spring application based on the Jar dependencies that you have added. Autoconfiguration can speed up and simplify development by removing the need to define some beans that are part of the auto-configuration classes.

Opinionated:
Spring Boot just decides on a set of default configured beans which you can override if you want. For example if you include the spring boot starter pom for jpa, you'll get auto-configured for you an in memory database, a hibernate entity manager, and a simple data source. This is an example of an opinionated (Spring's opinion that it's a good starting point) default configuration that you can override.

Bill of Material:
The preset list of possible combination of jars that work well without any issue is called bill of material. There are certain combination of jars and their version that work well and approved by the Spring boot. So all we need to do is pick that version of that list and we get all the preset value with it so we don’t have to worry about individual version numbers anymore. We just need to have version of the parent only

Embedded Tomcat Server:
Convenience: Don’t have to download and install and all.
Servlet Container Config is now application config: In tomcat we also need to do some default configuration, but with tomcat embedded we don’t have to do it as this is part of the application config. Because everything is in one package.
Useful for micro services architecture: We don’t have to do additional steps to deploy each micro services separately.

CrudRepository:
Having default CRUD operation we have to just call the same. However if we want some new methods we have to declare the correct method name without implementing the same. Example: If I need to search courses by topic Id and there is a reference of topic class in course class, then the method declaration would be like, FindBy>. Since we have a reference of another class we have to give the property name for that class also.

@Controller vs @RestController

@Controller is used to create web controllers that return views, which is further resolved by view resolver, while @RestController is used to create web services that return JSON or XML data. @RestController is a convenience annotation that does nothing more than adding the @Controller and @ResponseBody annotations The @ResponseBody is activated by default when @RestController is used. You don't need to add it above the function signature. With @RestController it will automatically convert the return object to JSON format or list or retun objects to JSON format, we don’t have to explicitly mention the return type.

@SpringBootApplication vs @EnableAutoConfiguration

@EnableAutoConfiguration annotation tells Spring Boot to "guess" how you will want to configure Spring, based on the jar dependencies that you have added. For example, If HSQLDB is on your classpath and you have not manually configured any database connection beans, then Spring will auto-configure an in-memory database.
@ComponentScan tells Spring to look for other components, configurations, and services in the specified package. Spring is able to auto scan, detect and register your beans or components from pre-defined project package. If no package is specified current class package is taken as the root package.
If you need Spring boot to Auto configure every thing for you @EnableAutoConfiguration is required. You don't need to add it manually, spring will add it internally for you based on the annotation you provide.
@SpringBootApplication annotation is equivalent to using @Configuration, @EnableAutoConfiguration and @ComponentScan with their default attributes.

@Configuration vs @Component

@Configuration Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime.
@Component Indicates that an annotated class is a "component". Such classes are considered as candidates for auto-detection when using annotation-based configuration and classpath scanning.
@Configuration is meta-annotated with @Component, therefore @Configuration classes are candidates for component scanning But you do can create i.e MyConfiguration.java class then stereotype with @Component and add @Beans declaration to it. In this way it will looks as a configuration, main difference is that when annotated class with @Configuration @Bean annotated methods are proxy using CGLIB which made in code calls after the first one to return bean from context instead of execute method again and create another instance as happens when using @Component with @Bean

The @Produces Annotation

The @Produces annotation is used to specify the MIME media types or representations a resource can produce and send back to the client. If @Produces is applied at the class level, all the methods in a resource can produce the specified MIME types by default. If it is applied at the method level, it overrides any @Produces annotations applied at the class level.
If no methods in a resource are able to produce the MIME type in a client request, the Jersey runtime sends back an HTTP “406 Not Acceptable” error.
The value of @Produces is an array of String of MIME types. For example:
@Produces({"image/jpeg,image/png"})
@Produces({"application/xml", "application/json"})

The @Consumes Annotation

The @Consumes annotation is used to specify which MIME media types of representations a resource can accept, or consume, from the client. If @Consumes is applied at the class level, all the response methods accept the specified MIME types by default. If @Consumes is applied at the method level, it overrides any @Consumes annotations applied at the class level.
If a resource is unable to consume the MIME type of a client request, the Jersey runtime sends back an HTTP “415 Unsupported Media Type” error.
The value of @Consumes is an array of String of acceptable MIME types. For example:
@Consumes({"text/plain,text/html"})

Jackson Annotations

The @JsonIgnore annotation marks a field in a POJO to be ignored by Jackson during serialization and deserialization. Jackson ignores the field in both JSON serialization and deserialization.

The @JsonIgnoreProperties annotation is used at the class level to ignore fields during serialization and deserialization. The properties that are declared in this annotation will not be mapped to the JSON content.
Example: @JsonIgnoreProperties({"userId","gender"})

The @JsonIgnoreType annotation is used to mark a class to be ignored during serialization and deserialization. It marks all the properties of the class to be ignored while generating and reading JSON.

The @JsonAutoDetect annotation is used at the class level to tell Jackson to override the visibility of the properties of a class during serialization and deserialization.

Annotations

@ResponseBody annotation in the method level, Spring will convert the return object in to the http response body.
@ResponseEntity works similar as @ResponseBody annotation. But when you create ResponseEntity object, you can add the response header to the http response as well. If you use ResponseEntity as return object, then you don’t need to use @ResponseBody annotation.
@RequestBody annotation aside the parameter in a method, Spring will convert the http request body to that declare class type in the method signature.
@HttpEntity works smilar as @RequestBody annotation. Plus you can access the http header from HttpEntity object, which @RequestBody annotation doesn’t offer. If you use HttpEntity as parameter object, then you don’t need to use @RequestBody annotation.

@Autowired and @Inject
Matches by Type
Restricts by Qualifiers
Matches by Name

@Resource
Matches by Name
Matches by Type
Restricts by Qualifiers (ignored if match is found by name)

Which annotations (or combination of) should I use for injecting my beans?
Explicitly name your component [@Component("beanName")]
Use @Resource with the name attribute [@Resource(name="beanName")]

Why should I not use @Qualifier?
Avoid @Qualifier annotations unless you want to create a list of similar beans. For example you may want to mark a set of rules with a specific @Qualifier annotation. This approach makes it simple to inject a group of rule classes into a list that can be used for processing data.

Does bean injection slow my program?
Scan specific packages for components [context:component-scan base-package="com.sourceallies.person"]. While this will result in more component-scan configurations it reduces the chance that you’ll add unnecessary components to your Spring context.

@Bean To declare a bean, simply annotate a method with the @Bean annotation. When JavaConfig encounters such a method, it will execute that method and register the return value as a bean within a BeanFactory. By default, the bean name will be the same as the method name.

@Component is an annotation that allows Spring to detect our custom beans automatically. In other words, without having to write any explicit code, Spring will:
Scan our application for classes annotated with @Component
Instantiate them and inject any specified dependencies into them
Inject them wherever needed
< context:component-scan > only scans @Component and does not look for @Controller, @Service and @Repository in general. They are scanned because they themselves are annotated with @Component

@Controller The @Controller annotation indicates that a particular class serves the role of a controller. The @Controller annotation acts as a stereotype for the annotated class, indicating its role.
What’s special about @Controller?
We cannot switch this annotation with any other like @Service or @Repository, even though they look same. The dispatcher scans the classes annotated with @Controller and detects methods annotated with @RequestMapping annotations within them. We can use @RequestMapping on/in only those methods whose classes are annotated with @Controller and it will NOT work with @Component, @Service, @Repository etc...

@Service @Service beans hold the business logic and call methods in the repository layer.
What’s special about @Controller?
Apart from the fact that it's used to indicate, that it's holding the business logic, there’s nothing else noticeable in this annotation; but who knows, Spring may add some additional exceptional in future.

@Repository This is to indicate that the class defines a data repository.
What’s special about @Controller?
In addition to pointing out, that this is an Annotation based Configuration, @Repository’s job is to catch platform specific exceptions and re-throw them as one of Spring’s unified unchecked exception. For this, we’re provided with PersistenceExceptionTranslationPostProcessor, that we are required to add in our Spring’s application context like this:
< bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

This bean post processor adds an advisor to any bean that’s annotated with @Repository so that any platform-specific exceptions are caught and then re-thrown as one of Spring’s unchecked data access exceptions.

DataAccessException translation
The @Repository annotation can have a special role when it comes to converting database exceptions to Spring-based unchecked exceptions.
For example, when we work with Hibernate and we do not use a Spring template (e.g. JdbcTemplate) to interact with database. In this case, if hibernate threw an exception then spring will not convert it to Spring-based exception.
To automatically convert such non-spring exceptions to spring exceptions, we shall annotate Hibernate DAOs with @Repository. This way, PersistenceExceptionTranslationPostProcessor will applly persistence exception translation and converts native resource exceptions to Spring’s DataAccessException hierarchy.

Bean Exceptions

NoSuchBeanDefinitionException Exception thrown when a BeanFactory is asked for a bean instance for which it cannot find a definition. This may point to a non-existing bean, a non-unique bean, or a manually registered singleton instance without an associated bean definition.
Suppose there is one object reference in the class that we are not creating the object of that class( is not defined in the Spring Context) during application starts then we cannot use @Autowired (Required=true) it will throw above exception, Hence we need to put Required=false.

NoUniqueBeanDefinitionException.When we have a autowired reference of a interface or parent class without any qualifier and there are multiple child classes then above exception will be thrown.
Add Qualifier to resolve the type. @Qualifier("beanName")

Spring bean life cycle

Spring framework provides following 4 ways for controlling life cycle events of a bean:
InitializingBean (void afterPropertiesSet() throws Exception) and DisposableBean (void destroy() throws Exception) callback interfaces
InitializingBean interface allows a bean to perform initialization work after all necessary properties on the bean have been set by the container. The afterPropertiesSet() method is not a preferable way to initialize the bean because it tightly couples the bean class with the spring container. A better approach is to use “init-method” attribute in bean definition in applicationContext.xml.
DisposableBean interface allows a bean to get a callback before the Spring container destroys the bean.
Aware interfaces for specific behavior Spring Aware interfaces allow you to look into the inner workings of the Spring Framework. Through Spring Aware interfaces, you can access the Spring context, or Spring bean lifecycle events.
ApplicationContextAware: void setApplicationContext (ApplicationContext applicationContext) throws BeansException; Spring provides an ApplicationContextAware interface that allows beans access to the ApplicationContext For example, if your bean needs to look up some other beans. Similarly, if your bean needs access to some application file resource in your bean or even publish some application events, you need access to the ApplicationContext.
BeanNameAware: void setBeanName(String name); The BeanNameAware interface is implemented by beans that need access to its name defined in the Spring container.
BeanFactoryAware: void setBeanFactory (BeanFactory beanFactory) throws BeansException; Beans might need access to the bean factory that created it, to call any service from the bean factory. Should you need to obtain a reference to the bean factory, implement the BeanFactoryAware interface.
Custom init() and destroy() methods in bean configuration file
These methods can be defined in two ways: Bean local definition to a single bean and Global definition applicable to all beans defined in bean context
@PostConstruct and @PreDestroy annotations
@PostConstruct annotated method will be invoked after the bean has been constructed using default constructor and just before its instance is returned to requesting object.
@PreDestroy annotated method is called just before the bean is about to destroyed inside the bean container.

What is the use of ContextLoaderListener in Spring MVC?

The ContextLoaderListner is one of the essential components of the Spring MVC framework, probably the most important after the DispatcherServlet itself. It is used to create the root context and responsible for loading beans, which are shared by multiple DispatcherServlet like beans related to the service layer and data access layer. In general, When you develop Spring MVC based web application and also using Spring in the services layer, you need to provide two application-contexts. The first one is configured using ContextLoaderListener, and the other is set using DispatcherServlet. The DispatcherServlet is responsible for loading web component-specific beans like controllers, view resolvers, and handler mappings while, as I said before, ContextLoaderListener is accountable for loading middle-tier and data-tier beans which forms the back end of Spring applications.

The ContextLoaderListener is like any other Servlet listener, and it has to be declared in the deployment descriptor to listen to events. It listens for startup and shutdown of the server by implementing ServletContextListener and accordingly creates and destroys Spring-managed beans.

Though, web.xml is just one way to configure ContextLoaderListener in Spring MVC application. From Spring 3.1 and Servlet 3.0, you can also configure ContextLoaderListener without deployment descriptor and only using Java Configurations.