# Java Interview question-3

**Question 21: What is the stateless bean in spring? name it and explain it.**

A stateless session bean is a type of enterprise bean which is commonly used to do independent operations. It does not have any associated client state, but it may preserve its instance state.

**Question 22: How does the Spring boot auto-detect feature work?**

Spring Boot auto-configuration is based upon three things, classpath scanning, conditionals annotations and configuration properties. They use combination of these three things to setup default configuration for you.

Here’s **how auto-configuration works in Spring Boot**:

**1\. Classpath scanning:** Spring Boot scans the classpath for specific libraries and dependencies that are commonly used in typical Spring applications. These libraries are known as “starters” and they provide a set of pre-configured settings for specific use cases, such as web applications, data access, security, etc.

**2\. Conditionals:** Auto-configuration in Spring Boot relies on conditional logic to determine which configurations to apply based on the presence or absence of certain classes or properties in the classpath.

For example, if the application has the **“spring-web” starter in its classpath,** Spring Boot automatically configures a web-based application with default settings such as servlets, filters, and other web-related components.

**3\. Configuration properties:** Spring Boot *uses a set of predefined configuration properties* that are automatically bound to the corresponding Spring beans. These properties can be specified in various ways, such as through [`application.properties`](http://application.properties) or `application.yml` files, **environment variables**, command-line arguments, or custom property sources.

Auto-configuration uses these configuration properties to set up default values for various components in the application.

Here is an *nice diagram which explains how auto-configuration works in Spring Boot:*

![](https://miro.medium.com/v2/resize:fit:875/0*SN4gyQ0lJfOlMFw1.png align="left")

Spring Boot also provides various mechanisms for developers t*o customize the auto-configuration process*. For example, **developers can exclude specific auto-configuration classes**, specify their own configuration classes, or provide custom configuration properties to override the default settings.

Another worth remembering thing is that **Auto-configuration classes in Spring Boot are ordered based on their specificity,** allowing developers to control the order in which configurations are applied.

This allows for fine-grained control over the configuration process and allows developers to override default settings or provide custom configurations as needed.

In short, auto-configuration in Spring Boot simplifies the configuration process for Spring applications, reduces boilerplate code, and allows developers to quickly set up a fully functional Spring application with sensible default settings.

It **promotes convention over configuration**, allowing developers to focus on writing business logic rather than spending time on tedious configuration tasks.

**Question 23: How Spring Boot Configure JDBC and Kafka based upon JAR file? AutoConfiguration Example**

Here’s an example of how auto-configuration works in Spring Boot with the JDBC (Java Database Connectivity) starter:

When you include the `“spring-boot-starter-jdbc”` dependency in your Spring Boot application, Spring Boot automatically scans the classpath and detects the presence of the JDBC driver for your database, such as MySQL or PostgreSQL.

If JDBC drive is present then Spring Boot can also automatically configures a `DataSource` bean with default settings, such as connection pool properties, database URL, username, and password. It also configures a `JdbcTemplate` bean for simplified database operations.

Spring Boot provides default configuration properties for the DataSource bean, such as `“spring.datasource.url”`, `“spring.datasource.username”,` `and “spring.datasource.password”`. These properties can be specified in the [`application.properties`](http://application.properties) or `application.yml file`, and Spring Boot automatically binds them to the corresponding DataSource bean.

If you need to customize the default settings, you can specify your own configuration properties or provide custom configuration classes. For example, you can override the default DataSource settings with your own database properties, or you can provide a custom DataSource bean with specific configuration settings.

Similarly, auto-configuration works with other components in Spring Boot, such as Kafka and Microservices. For example, when you include the `“spring-kafka”` starter, Spring Boot automatically configures Kafka-related beans, such as `KafkaTemplate` and `KafkaListenerContainer`, based on the presence of the Kafka client library.

Similarly, when you include the `“spring-cloud-starter-netflix-eureka-client”` starter for building Microservices with Eureka, Spring Boot automatically configures a `EurekaClient` bean for service discovery and registration with Eureka server.

Overall, auto-configuration in Spring Boot simplifies the configuration process for various components, reduces boilerplate code, and allows developers to quickly set up fully functional applications with sensible default settings.

**Question 24: What are pros and cons of Auto-configuration?**

Here are Pros of Auto-Configuration in Spring Boot:

**1\. Simplified configuration:** Auto-configuration automatically configures beans and settings based on the presence of dependencies in the classpath, reducing the need for manual configuration. This simplifies the configuration process and reduces boilerplate code.

**2\. Faster development:** Auto-configuration allows developers to quickly set up a fully functional application with sensible default settings, enabling faster development and prototyping. It eliminates the need to spend time on manual configuration and allows developers to focus on writing business logic.

**3\. Flexibility:** Auto-configuration in Spring Boot provides flexibility to override default settings and customize the behavior of beans as needed. Developers can specify their own configuration properties or provide custom configuration classes to customize the auto-configured beans according to their requirements.

**4\. Consistency:** Auto-configuration promotes consistency across Spring Boot projects by providing standardized configuration patterns for different components. This ensures that similar components in different projects follow the same configuration conventions, making it easier to maintain and understand the configuration across different projects.

There is no free lunch, everything comes at the cost of something and auto-configuration is no exception

Here are Cons of Auto-Configuration in Spring Boot:

**1\. Potential conflicts:** Auto-configuration relies on classpath scanning and conditionals to determine the presence of dependencies, which can potentially result in conflicts if multiple dependencies provide conflicting auto-configuration settings. This may require manual intervention to resolve conflicts and ensure correct configuration.

**2\. Reduced visibility:** Auto-configuration may hide complex configuration details and make it difficult to understand the exact configuration being applied. Developers may need to refer to the Spring Boot documentation or source code to understand the underlying auto-configuration logic, which can be challenging for complex configurations.

**3\. Overriding default behavior:** While auto-configuration provides flexibility to override default settings, it may require additional effort to customize the behavior of auto-configured beans. Developers need to be aware of the auto-configuration logic and the sequence of configurations to properly override the default behavior.

**4\. Version compatibility:** Auto-configuration is dependent on the versions of dependencies present in the classpath. In case of version conflicts or changes in auto-configuration behavior between different versions of dependencies, it may require manual intervention to ensure compatibility and proper functioning of the application.

**Question 25: Can you disable auto-configuration in spring boot?**

Yes, it is possible to disable auto-configuration in Spring Boot by using the `exclude` attribute of the `@EnableAutoConfiguration` annotation or by specifying the `spring.autoconfigure.exclude` property in the application properties or YAML file.

This is also one of the follow up question interviewer ask on Spring boot interviews.

Here’s how you can disable auto-configuration using the `exclude` attribute of `@EnableAutoConfiguration` annotation:

```java
@SpringBootApplication
@EnableAutoConfiguration(exclude = {
                  AutoConfigurationClass1.class, 
                  AutoConfigurationClass2.class})
public class NewSpringBootApplication {
    // ...
}
```

In the above example, `AutoConfigurationClass1` and `AutoConfigurationClass2` are the classes of the auto-configuration classes that you want to exclude from being applied.

Alternatively, you can specify the `spring.autoconfigure.exclude` property in the application properties or YAML file, like this:

```java
spring.autoconfigure.exclude=\
com.example.AutoConfigurationClass1,\
com.example.AutoConfigurationClass2
```

In the above example, `com.example.AutoConfigurationClass1` and `com.example.AutoConfigurationClass2` are the fully qualified class names of the auto-configuration classes that you want to exclude from being applied.

Disabling auto-configuration can be useful in cases where you want to explicitly control the configuration of beans or when you want to avoid conflicts between different auto-configuration classes.

However, it should be used with caution, as it may affect the expected behaviour of the Spring Boot application and may require manual configuration for certain components or features.

**Question 26: What is difference between @EnableAutoConfiguration and @SpringBootApplication in Spring Boot Application?**

As we already know, `@EnableAutoConfiguration` and `@SpringBootApplication` are both annotations used in Spring Boot applications, but they have different purposes and usage.

`@EnableAutoConfiguration`**:** This annotation is used to enable auto-configuration in a Spring Boot application. It allows Spring Boot to automatically configure the application’s beans, based on the classpath and other configurations.

It scans the classpath for available configurations, and automatically configures the application with sensible defaults for various components, such as data sources, web servers, and message brokers, among others.

It is often used in combination with other annotations, such as `@Configuration` and `@ComponentScan`, to define additional configuration classes and customize the auto-configuration behavior.

`@SpringBootApplication:` This is a meta-annotation that combines multiple annotations, including `@EnableAutoConfiguration`, `@ComponentScan`, and `@Configuration`, into a single annotation.

It is typically used as the main annotation for the main class of a Spring Boot application. It enables auto-configuration, component scanning, and marks the class as a configuration class, allowing it to define beans and other application-specific configurations.

It provides a convenient way to bootstrap a Spring Boot application with sensible defaults and enables the application to start as a standalone, executable JAR file.

In summary, while `@EnableAutoConfiguration` is used to specifically enable auto-configuration in a Spring Boot application, `@SpringBootApplication` is a meta-annotation that combines multiple annotations, including `@EnableAutoConfiguration`, to provide a convenient way to bootstrap a Spring Boot application with sensible defaults and configuration capabilities.

Here is another nice diagram which shows how @SpringBootApplication annotation can enable auto-configuration in Spring boot.

![](https://miro.medium.com/v2/resize:fit:875/0*typhY75jUXXp73so.png align="left")

**Question 27: What is Spring Bean Life Cycle?**

The figure below shows two parts of the Spring bean lifecycle:

![](https://miro.medium.com/v2/resize:fit:875/0*XXIvueMFT2NWOddZ.png align="left")

**Part 1:** Shows the different stages a bean goes through after instantiation until it is ready for use.  
**Part 2:** Shows what happens to a bean once the Spring IoC container shuts down.

As you can see in Part 1 of the preceding figure, the container instantiates a bean by calling its constructor and then populates its properties.

This is followed by several calls to the bean until the bean is in the ready state.

Similarly, as shown in Part 2, when the container shuts down, the container calls the bean to enable it to perform any required tasks before the bean is destroyed.

**Question 28: What are bean scopes and what are prototype and request bean scopes?**

When you create a bean definition what you are actually creating is a *recipe* for creating actual instances of the class defined by that bean definition. The idea that a bean definition is a recipe is important because it means that, just like a class, you can potentially have many object instances created from a single recipe.

***ScopeDescription****:*

**S**[**ingleton**](https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch04s04.html#beans-factory-scopes-singleton)\-Scopes a single bean definition to a single object instance per Spring IoC container.

**P**[**rototype**](https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch04s04.html#beans-factory-scopes-prototype) — Scopes a single bean definition to any number of object instances.

**R**[**equest**](https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch04s04.html#beans-factory-scopes-request)\-Scopes a single bean definition to the lifecycle of a single HTTP request; that is each and every HTTP request will have its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring `ApplicationContext`.

**S**[**ession**](https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch04s04.html#beans-factory-scopes-global-session)\-Scopes a single bean definition to the lifecycle of a HTTP `Session`. Only valid in the context of a web-aware Spring `ApplicationContext`.

**G**[**lobal session**](https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch04s04.html#beans-factory-scopes-global-session)\-Scopes a single bean definition to the lifecycle of a global HTTP `Session`. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring `ApplicationContext`.

**Question 29: What is the Difference between @Component and @Service @respository @Controller annotations?**

Purpose of each annotation:

1. `@Controller` -&gt; Classes annotated with this, are intended to receive a request from the client side. The first request comes to the Dispatcher Servlet, from where it passes the request to the particular controller using the value of `@RequestMapping` annotation.
    
2. `@Service` -&gt; Classes annotated with this, are intended to manipulate data, that we receive from the client or fetch from the database. All the manipulation with data should be done in this layer.
    
3. `@Repository` -&gt; Classes annotated with this, are intended to connect with the database. It can also be considered as DAO(Data Access Object) layer. This layer should be restricted to CRUD (create, retrieve, update, delete) operations only. If any manipulation is required, data should be sent be send back to the @Service layer.
    
4. Technically `@Controller`, `@Service`, `@Repository` are all same. All of them extends `@Component`.
    
5. From the Spring source code:
    
6. 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.
    
7. We can directly use `@Component` for each and every bean, but for better understanding and maintainability of a large application, we use `@Controller`, `@Service`, `@Repository`.
    

**Question 30: How would you call a method before starting/loading a Spring boot application(Printing Spring Boot Banner)?**

Her we will see how to **run logic at the startup of a Spring application.**

**1\. Running Logic on Startup**

Running logic during/after Spring application’s startup is a common scenario. But it’s also one that causes multiple problems.

In order to benefit from Inverse of Control, we need to renounce partial control over the application’s flow to the container. This is why instantiation, setup logic on startup, etc. need special attention.

We can’t simply include our logic in the beans’ constructors or call methods after instantiation of any object because we aren’t in control during those processes.

Let’s look at a real-life example:

```java
@Component
public class InvalidInitExampleBean {
    @Autowired
    private Environment env;
    public InvalidInitExampleBean() {
        env.getActiveProfiles();
    }
}
```

Here we’re trying to access an *autowired* field in the constructor. When the constructor is called, the Spring bean is not yet fully initialized. This is a problem because **calling fields that are not yet initialized will result in *NullPointerException*s.**

Let’s look at a few ways Spring gives us to manage this situation.

**1.1. The @PostConstruct Annotation**

We can use Javax’s *@PostConstruct* annotation for annotating a method that should be run **once immediately after the bean’s initialization.** Keep in mind that Spring will run the annotated method even if there is nothing to inject.

Here’s *@PostConstruct* in action:

```java
@Component
public class PostConstructExampleBean {
    private static final Logger LOG 
      = Logger.getLogger(PostConstructExampleBean.class);
    @Autowired
    private Environment environment;
    @PostConstruct
    public void init() {
        LOG.info(Arrays.asList(environment.getDefaultProfiles()));
    }
}
```

We can see that the *Environment* instance was safely injected and then called in the *@PostConstruct* annotated method without throwing a *NullPointerException*.

**1.2. The InitializingBean Interface**

The *InitializingBean* approach works in a similar way. Instead of annotating a method, we need to implement the *InitializingBean* interface and the *afterPropertiesSet()* method.

Here we implement the previous example using the *InitializingBean* interface:

```java
@Component
public class InitializingBeanExampleBean implements InitializingBean {
    private static final Logger LOG 
      = Logger.getLogger(InitializingBeanExampleBean.class);
    @Autowired
    private Environment environment;
    @Override
    public void afterPropertiesSet() throws Exception {
        LOG.info(Arrays.asList(environment.getDefaultProfiles()));
    }
}
```

**1.3. An ApplicationListener**

We can use this approach for **running logic after the Spring context has been initialized.** So, we aren’t focusing on any particular bean. We’re instead waiting for all of them to initialize.

In order to do this, we need to create a bean that implements the *ApplicationListener&lt;ContextRefreshedEvent&gt;* interface:

```java
@Component
public class StartupApplicationListenerExample implements 
  ApplicationListener<ContextRefreshedEvent> {
private static final Logger LOG 
      = Logger.getLogger(StartupApplicationListenerExample.class);
    public static int counter;
    @Override public void onApplicationEvent(ContextRefreshedEvent event) {
        LOG.info("Increment counter");
        counter++;
    }
}
```

We can get the same results by using the newly introduced *@EventListener* annotation:

```java
@Component
public class EventListenerExampleBean {
    private static final Logger LOG 
      = Logger.getLogger(EventListenerExampleBean.class);
    public static int counter;
    @EventListener
    public void onApplicationEvent(ContextRefreshedEvent event) {
        LOG.info("Increment counter");
        counter++;
    }
}
```

We want to make sure to pick an appropriate event for our needs. In this example, we chose the *ContextRefreshedEvent*.

**1.4. The @Bean initMethod Attribute**

We can use the *initMethod* property to run a method after a bean’s initialization.

Here’s what a bean looks like:

```java
public class InitMethodExampleBean {
    private static final Logger LOG = 
              Logger.getLogger(InitMethodExampleBean.class);
    @Autowired
    private Environment environment;
    public void init() {
        LOG.info(Arrays.asList(environment.getDefaultProfiles()));
    }
}
```

Notice we haven’t implemented any special interfaces or used any special annotations.

Then we can define the bean using the *@Bean* annotation:

```java
@Bean(initMethod="init")
public InitMethodExampleBean initMethodExampleBean() {
    return new InitMethodExampleBean();
}
```

And this is how a bean definition looks in an XML config:

```java
<bean id="initMethodExampleBean"
  class="com.baeldung.startup.InitMethodExampleBean"
  init-method="init">
</bean>
```

**1.5. Constructor Injection**

If we’re injecting fields using Constructor Injection, we can simply include our logic in a constructor:

```java
@Component 
public class LogicInConstructorExampleBean {
    private static final Logger LOG 
      = Logger.getLogger(LogicInConstructorExampleBean.class);
    private final Environment environment;
    @Autowired
    public LogicInConstructorExampleBean(Environment environment) {
        this.environment = environment;
        LOG.info(Arrays.asList(environment.getDefaultProfiles()));
    }
}
```

**1.6. Spring Boot CommandLineRunner**

Spring Boot provides a *CommandLineRunner* interface with a callback *run()* method. This can be invoked at application startup after the Spring application context is instantiated.

Let’s look at an example:

```java
@Component
public class CommandLineAppStartupRunner implements CommandLineRunner {
    private static final Logger LOG =
      LoggerFactory.getLogger(CommandLineAppStartupRunner.class);
    public static int counter;
    @Override
    public void run(String...args) throws Exception {
        LOG.info("Increment counter");
        counter++;
    }
}
```

**Note**: As mentioned in the [documentation](https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/CommandLineRunner.html), multiple *CommandLineRunner* beans can be defined within the same application context and can be ordered using the *@Ordered* interface or *@Order* annotation.

**1.7. Spring Boot ApplicationRunner**

Similar to *CommandLineRunner*, Spring Boot also provides an *ApplicationRunner* interface with a *run()* method to be invoked at application startup. However, instead of raw *String* arguments passed to the callback method, we have an instance of the [*ApplicationArguments*](https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/ApplicationArguments.html) class.

The *ApplicationArguments* interface has methods to get argument values that are options and plain argument values. An argument that is prefixed with — — is an option argument.

Let’s look at an example:

```java
@Component
public class AppStartupRunner implements ApplicationRunner {
    private static final Logger LOG =
      LoggerFactory.getLogger(AppStartupRunner.class);
    public static int counter;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        LOG.info("Application started with option names : {}", 
          args.getOptionNames());
        LOG.info("Increment counter");
        counter++;
    }
}
```

**2\. Combining Mechanisms**

In order to have full control over our beans, we could combine the above mechanisms together.

This is the order of execution:

1. constructor
    
2. *@PostConstruct* annotated methods
    
3. InitializingBean’s *afterPropertiesSet()* method
    
4. initialization method specified as *init-method* in XML
    

Let’s create a Spring bean that combines all mechanisms:

```java
@Component
@Scope(value = "prototype")
public class AllStrategiesExampleBean implements InitializingBean {
    private static final Logger LOG 
      = Logger.getLogger(AllStrategiesExampleBean.class);
    public AllStrategiesExampleBean() {
        LOG.info("Constructor");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        LOG.info("InitializingBean");
    }
    @PostConstruct
    public void postConstruct() {
        LOG.info("PostConstruct");
    }
    public void init() {
        LOG.info("init-method");
    }
}
```

If we try to instantiate this bean, we can see logs that match the order specified above:

```java
[main] INFO o.b.startup.AllStrategiesExampleBean - Constructor
[main] INFO o.b.startup.AllStrategiesExampleBean - PostConstruct
[main] INFO o.b.startup.AllStrategiesExampleBean - InitializingBean
[main] INFO o.b.startup.AllStrategiesExampleBean - init-method
```

[  
](https://medium.com/@cs.vivekgupta?source=post_page-----67d0d21bab94--------------------------------)
