Learn with best explanation

Coding tutorials and solutions

Spring Framework Success Secrets 2024: Expert Tips And Premium Insights on Spring Bean - Chapter 3's Must-Know Interview Questions


Welcome to Chapter 3 of Spring Framework Success Secrets 2024 Explore the depths of Spring through insightful interviews, unraveling the intricacies of @Autowired annotation, autowiring types, and essential interview questions. Delve into bean scopes, discover the power of @Bean and @Configuration annotations, and master strategies for handling exceptions and cyclic dependencies. Elevate your Spring expertise with exclusive insights and expert tips, ensuring a triumphant journey in your interviews and beyond.

How @Autowire annotation works?

The functionality of the @Autowired annotation involves employing reflection to identify the suitable dependency for injection. Initially, it seeks a bean with a matching type to the dependency. Should it not locate a bean of the same type, the next step involves searching for a bean with a qualifier matching the dependency's name. Failure to find an appropriate bean for injection results in an exception being thrown.

What are the Types of Autowiring?

There are four types of autowiring that the @Autowired annotation supports:

  • ByType: This is the default type of autowiring. The Spring Framework will look for a bean with the same type as the dependency.
  • ByName: The Spring Framework will look for a bean with the same name as the dependency.
  • ByConstructor: The Spring Framework will look for a constructor that takes a single argument of the type of the dependency.
  • ByQualifier: The Spring Framework will look for a bean with a qualifier that matches the specified value.

How to exclude a Bean from Autowiring?

In Spring’s XML format, set the autowire-candidate attribute of the <bean/> element to false. The container makes that specific bean definition unavailable to the autowiring infrastructure (including annotation style configurations such as @Autowired ).

Difference between @Autowire and @Inject in spring?

The usage of @Autowired and @Inject The usage of @Autowired and @Inject annotations is common for achieving dependency injection in Spring applications. Yet, distinctions exist between the two annotations in their functionality

@Autowired(Use when developing a Spring application)

The @Autowired annotation, exclusive to Spring, serves the purpose of injecting dependencies into beans under the management of the Spring container. The @Autowired annotation can be used with all four types of autowiring: byType, byName, byConstructor, and byQualifier.

@Inject(Use when developing a non-Spring application)

The @Inject annotation, a standard JSR-330 annotation, facilitates dependency injection into beans managed by any dependency injection container that adheres to JSR-330. The @Inject annotation can only be used with byType and byName autowiring.

Is Singleton bean thread safe?

No, singleton beans are not thread safe by default. This means that if two threads try to access a singleton bean at the same time, they may get conflicting results. This is because singleton beans are shared across all threads, and any changes made to a singleton bean by one thread will be visible to all other threads.

Difference between Singleton and prototype bean?

Feature Singleton Prototype
Scope Application-wide Per-request
Instances One Multiple
Use cases Stateless beans Stateful beans

What is @Bean annotation in spring?

The @Bean annotation in Spring marks a method as a bean definition, guiding the Spring container on creating and handling beans. When using @Bean, the container generates an instance of the specified bean class from the method and oversees its lifecycle.

@Configuration
    public class MyConfiguration {
        @Bean
        public MyService myService() {
            return new MyServiceImpl();
        }
    }

In this example, the myService() method is annotated with @Bean. This tells the Spring container to create an instance of the MyServiceImpl class and manage its lifecycle. The bean can then be injected into other beans using the @Autowired annotation.

What is @Configuration annotation?

The @Configuration annotation is a Spring Framework annotation that marks a class as a configuration class. Configuration classes are used to define beans in a Spring application. When a class is annotated with @Configuration, the Spring container will scan the class for methods that are annotated with @Bean and use those methods to define beans.

 @Configuration
    public class MyConfiguration {
        @Bean
        public MyService myService() {
            return new MyServiceImpl();
        }
    }

What is the stateless bean in spring? name it and explain it?

A stateless bean in Spring Framework is a bean that does not maintain any state between method invocations. This means that the bean does not store any information about the previous invocations, and each method call is handled independently.

Stateless beans are commonly employed for services that execute actions or calculations without storing information between tasks. These services might involve performing math operations, accessing external resources, or handling tasks that don't need the bean to remember past actions.

Singleton beans, like stateless beans, don't keep track of previous actions, making them suitable for sharing among multiple users. This simplicity allows easy horizontal scaling by adding more instances to manage higher workloads.

Stateless beans are simpler and easier to understand because they don't store information between tasks. Also, since they don't keep any data, they can be easily copied and used in multiple locations for better availability and scalability.

How is the bean injected in spring?

In Spring, a bean is injected (or wired) into another bean using the Dependency Injection (DI) pattern. DI is a design pattern that allows a class to have its dependencies provided to it, rather than creating them itself.
Spring provides several ways to inject beans into other beans, including:

Constructor injection:

A bean can be injected into another bean by passing it as a constructor argument. Spring will automatically create an instance of the dependent bean and pass it to the constructor.

 public class BeanA {
        private final BeanB beanB;
        public BeanA(BeanB beanB) {
            this.beanB = beanB;
        }
    }

Setter injection:

A bean can be injected into another bean by passing it as a setter method argument. Spring will automatically call the setter method and pass the dependent bean.

 public class BeanA {
        private BeanB beanB;
        @Autowired
        public void setBeanB(BeanB beanB) {
            this.beanB = beanB;
        }
    }

Field injection

:

A bean can be injected into another bean by annotating a field with the @Autowired annotation. Spring will automatically set the field with the dependent bean.

public class BeanA {
 @Autowired
 private BeanB beanB;
}

Interface injection:

A bean can be injected into another bean by implementing an interface. Spring will automatically set the field with the dependent bean.

public class BeanA implements BeanBUser {
        @Autowired
        private BeanB beanB;
}

You have the flexibility to use different methods for injecting beans, and your choice depends on the specific needs of your application. Spring employs Autowiring to connect beans automatically, and this can be based on type, name, or constructor. By default, Spring attempts to autowire by type, resorting to autowiring by name if there are multiple beans of the same type, as defined in the configuration file.

How to handle cyclic dependency between beans?

Let’s say for example: Bean A is dependent on Bean B and Bean B is dependent on Bean A. How does the spring container handle eager & lazy loading?
A cyclic dependency between beans occurs when two or more beans have a mutual dependency on each other, which can cause issues with the creation and initialization of these beans.
There are several ways to handle cyclic dependencies between beans in Spring:

Lazy Initialization:

By using the @Lazy annotation on one of the beans involved in the cycle, it can be initialized only when it is actually needed.

@Lazy
@Autowired
private BeanA beanA;

Constructor injection:

Instead of using setter or field injection, you can use constructor injection, which will make sure that the dependencies are provided before the bean is fully initialized.

 public class BeanA {
        private final BeanB beanB;
        public BeanA(BeanB beanB) {
            this.beanB = beanB;
        }
    }

Use a proxy:

A proxy can be used to break the cycle by delaying the initialization of one of the beans until it is actually needed. Spring AOP can be used to create a proxy for one of the beans involved in the cycle.

Use BeanFactory:

Instead of injecting the bean directly, you can use BeanFactory to retrieve the bean when it's actually needed.

public class BeanA {
        private BeanB beanB;
        @Autowired
        public BeanA(BeanFactory beanFactory) {
            this.beanB = beanFactory.getBean(BeanB.class);
        }
    }

What would you call a method before starting/loading an Spring boot application?

In Spring Boot, there are several methods that can be called before starting or loading a Spring Boot application. Some of the most commonly used methods are:

main() method:

The main() method is typically the entry point of a Spring Boot application. It is used to start the Spring Boot application by calling the SpringApplication.run() method.

@PostConstruct method:

The @PostConstruct annotation can be used to mark a method that should be called after the bean has been constructed and all dependencies have been injected. This can be used to perform any necessary initialization before the application starts.

CommandLineRunner interface:

The CommandLineRunner interface can be implemented by a bean to run specific code after the Spring Application context has been loaded.

ApplicationRunner interface:

The ApplicationRunner interface can be implemented by a bean to run specific code after the Spring Application context has been loaded and the Application arguments have been processed.

EventListener :

The @EventListener annotation can be used to register a method to listen to specific Application events like ApplicationStartingEvent, ApplicationReadyEvent and so on.

How to handle exceptions in the spring framework?

There are several ways to handle exceptions in the Spring Framework:

try-catch block:

You can use a try-catch block to catch and handle exceptions in the method where they occur. This approach is useful for handling specific exceptions that are likely to occur within a particular method.

@ExceptionHandler annotation:

You can use the @ExceptionHandler annotation on a method in a @Controller class to handle exceptions that are thrown by other methods in the same class. This approach is useful for handling specific exceptions in a centralized way across multiple methods in a controller.

@ControllerAdvice annotation:

You can use the @ControllerAdvice annotation on a class to define a global exception handler for multiple controllers in your application. This approach is useful for handling specific exceptions in a centralized way across multiple controllers.

HandlerExceptionResolver interface:

You can implement the HandlerExceptionResolver interface to create a global exception handler for your entire application. This approach is useful for handling specific exceptions in a centralized way across the entire application.

ErrorPage:

You can define an ErrorPage in your application to redirect to a specific page when a certain exception occurs. This approach is useful for displaying a user-friendly error page when an exception occurs.

@ResponseStatus annotation:

You can use the @ResponseStatus annotation on an exception class to define the HTTP status code that should be returned when the exception is thrown.

How filter work in spring?

In Spring, filters act as interceptors for requests and responses, processing them before and after they reach the actual application logic. They're like gatekeepers that can modify, deny, or allow requests based on predefined rules.

Here's how they work in a nutshell:

  • Configuration:
    • You define filters as beans in your Spring configuration.
    • Specify the order in which filters should be executed.
  • Request Flow:
    • When a client sends a request, it goes through each filter in the specified order.
    • Each filter can Inspect the request headers, body, and other attributes.
    • Modify the request content or headers.
    • Decide to continue processing the request or terminate it.
  • Response Flow:
    • Once the request reaches the application logic and receives a response, the response flows back through the filters in reverse order.
    • Filters can again Inspect the response headers and body.
    • Modify the response content or headers.
  • Common Use Cases:
    • Security filters: Validate user authentication, authorize access, and prevent security vulnerabilities.
    • Logging filters: Log information about requests and responses for debugging and analysis.
    • Compression filters: Compress responses to reduce bandwidth usage.
    • Caching filters: Cache frequently accessed resources to improve performance.

Benefits:

    • Intercept and modify requests and responses: Provide more control over application behavior.
    • Centralize common tasks: Avoid duplicating code for security, logging, etc.
    • Chain multiple filters: Achieve complex processing logic by combining multiple filters.