0% found this document useful (0 votes)
3 views8 pages

Spring Life Cycle

Uploaded by

mariagemariagee5
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views8 pages

Spring Life Cycle

Uploaded by

mariagemariagee5
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Spring LifeCycle

Annotations & Interfaces that aims to manage and


visualize the state of beans

Instructor : Dr. BADR EL KHALYLY


Spring Provides annotations & Interfaces that aim to manage and visualize the state of bean from
creation, injection, ready to use by external user or external application, shutdown.

In initialization we can define a Custom :


The BeanPostProcessor interface in Spring allows developers to customize the bean initialization
process. It provides two methods that are invoked by the Spring container before and after a bean's
initialization logic is executed:
1. postProcessBeforeInitialization:
o Executes before any initialization callbacks (e.g., @PostConstruct,
afterPropertiesSet(), or a custom init-method) are called for the bean.
o This is where you can modify or process the bean before it is fully initialized.
2. postProcessAfterInitialization:
o Executes after all initialization callbacks are completed.
o This is where you can modify or wrap the fully initialized bean (e.g., to add proxying or
additional behavior).

In our Case we have :

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws
BeansException {
System.out.println("postProcessBeforeInitialization: " + beanName + " avant initialisation");
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws
BeansException {
System.out.println("postProcessAfterInitialization: " + beanName + " après initialisation");
return bean;
}
}

And for each Bean definition we can Implement two interfaces : DisposableBean, InitializingBean

The InitializingBean interface is a part of the Spring Framework's lifecycle management and is used
to define initialization logic for a bean. It provides a callback method, afterPropertiesSet(), which is
invoked by the Spring container after the bean's properties have been set and dependency
injection is complete.

The DisposableBean interface is part of Spring's lifecycle management. It is used to define


destruction logic for a bean, allowing you to release resources or perform cleanup operations when
the bean is being destroyed by the Spring container.
The interface provides a single method that can be overridden:

void destroy() throws Exception;


This method is automatically invoked by the Spring container when the bean is removed from the
container or the application context is shut down.
In particular we have :

@Component
public class MailNotificationService implements NotificationService, DisposableBean,
InitializingBean {

@PostConstruct
public void init() {
System.out.println("MailNotificationService initialisé.");
}

@PreDestroy
public void preDestroyMethod() {
System.out.println("MailNotificationService va être détruit.");
}

@Override
public void destroy() throws Exception {
System.out.println("MailNotificationService destroy() appelé.");
}

@Override
public void sendNotification(String message) {
System.out.println("Sending mail regarding " + message);
}

@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet : Méthode exécutée après @PostConstruct.");

}
}
And we create a main program that permits to an external user to intervene with our application
after initialization and injection, and after getting ready to use:

public class Main {


public static void main(String[] args) {
// Initialisation du contexte Spring
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

// Obtention du service à partir du contexte


RouteCoastService coastService = context.getBean(RouteCoastService.class);

try (Scanner scanner = new Scanner(System.in)) {


while (true) {
System.out.println("\n--- Menu ---");
System.out.println("1. Calculer le coût d'une route");
System.out.println("2. Fermer l'application (saisir CLOSEIT)");
System.out.print("Votre choix : ");
String userInput = scanner.nextLine();

if ("CLOSEIT".equalsIgnoreCase(userInput.trim())) {
System.out.println("Fermeture de l'application...");
break;
}

if ("1".equals(userInput.trim())) {
System.out.print("Entrez l'identifiant du véhicule : ");
String vehicleId = scanner.nextLine();

System.out.print("Entrez la distance parcourue (en km) : ");


double distance = scanner.nextDouble();

System.out.print("Entrez le coût par kilomètre : ");


double costPerKm = scanner.nextDouble();
scanner.nextLine(); // Consommer le retour à la ligne après nextDouble()

// Appel du service avec les données saisies


coastService.calculCoast(vehicleId, distance, costPerKm);
} else {
System.out.println("Commande inconnue. Essayez à nouveau.");
}
}
} catch (Exception e) {
System.err.println("Une erreur est survenue : " + e.getMessage());
} finally {
// Fermeture explicite du contexte
((AnnotationConfigApplicationContext) context).close();
System.out.println("Contexte Spring fermé.");
}
}
}
We got the log after running the application:

22:59:47.569 [main] INFO


org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorCheck
er - Bean 'appConfig' of type [config.AppConfig$$SpringCGLIB$$0] is not eligible for getting
processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
22:59:47.589 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory
- Creating shared instance of singleton bean 'mailNotificationService'
postProcessBeforeInitialization: mailNotificationService avant initialisation
MailNotificationService initialisé.
afterPropertiesSet : Méthode exécutée après @PostConstruct.
postProcessAfterInitialization: mailNotificationService après initialisation
22:59:47.595 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory
- Creating shared instance of singleton bean 'routeCoastService'
postProcessBeforeInitialization: routeCoastService avant initialisation
RouteCoastService initialisé.
afterPropertiesSet : Méthode exécutée après @PostConstruct.
postProcessAfterInitialization: routeCoastService après initialisation

--- Menu ---


1. Calculer le coût d'une route
2. Fermer l'application (saisir CLOSEIT)
Votre choix :

Bean Lifecycle in Spring Framework

The lifecycle of a bean in Spring involves multiple stages, each executed in a specific order to ensure
proper initialization and destruction. Here's an explanation of the lifecycle and how the provided
code demonstrates it:

1. Bean Instantiation
 Spring starts by instantiating the bean using its constructor or a factory method.

2. Dependency Injection
 Spring injects the required dependencies into the bean via @Autowired, setters, or
constructor arguments.

3. BeanPostProcessor (Before Initialization)


 postProcessBeforeInitialization: This method is executed for every bean that passes
through the container before any initialization callbacks like @PostConstruct or
InitializingBean are called.
Example Output:

postProcessBeforeInitialization: mailNotificationService avant initialisation


postProcessBeforeInitialization: routeCoastService avant initialisation

4. Initialization Callbacks
Spring provides several ways to execute custom logic during the initialization phase, in the following
order:
1. @PostConstruct:
o A method annotated with @PostConstruct is called after dependency injection.
o It is often used for initial setup that requires injected dependencies.
Example Output:
MailNotificationService initialisé.
RouteCoastService initialisé.
2. InitializingBean Interface (afterPropertiesSet Method):
o This method is called after @PostConstruct.
o It is used for initialization logic that needs to run after all properties are set.
Example Output:

afterPropertiesSet : Méthode exécutée après @PostConstruct.


3. BeanPostProcessor (After Initialization):
o postProcessAfterInitialization: This method is executed after all initialization
callbacks are completed.
o It can be used to modify the fully initialized bean before it is returned to the
application.
Example Output:

postProcessAfterInitialization: mailNotificationService après initialisation


postProcessAfterInitialization: routeCoastService après initialisation

5. Bean Usage
 The bean is now fully initialized and ready for use by the application.

6. Shutdown / Bean Destruction


During the shutdown phase, Spring ensures proper cleanup of beans. The destruction callbacks are
executed in the following order:
1. @PreDestroy:
o A method annotated with @PreDestroy is called before the bean is removed from the
container.
Example Output:

MailNotificationService va être détruit.


RouteCoastService va être détruit.
2. DisposableBean Interface (destroy Method):
o This method is executed after @PreDestroy.
o It is used for custom cleanup logic.
Example Output:

MailNotificationService destroy() appelé.


RouteCoastService destroy() appelé.

Summary of Interfaces and Annotations


1. @PostConstruct and @PreDestroy:
o Lifecycle annotations from Java’s javax.annotation package.
o @PostConstruct: Called after dependency injection.
o @PreDestroy: Called before bean destruction.
2. InitializingBean Interface (afterPropertiesSet Method):
o A Spring-provided interface.
o Ensures initialization logic after dependency injection.
3. DisposableBean Interface (destroy Method):
o A Spring-provided interface.
o Ensures cleanup logic before the bean is destroyed.
4. BeanPostProcessor Interface:
o Allows custom logic before and after initialization of beans.
o Methods:
 postProcessBeforeInitialization: Invoked before initialization callbacks.
 postProcessAfterInitialization: Invoked after initialization callbacks.

Visualization of Bean Lifecycle


1. Instantiation → Constructor is called.
2. Dependency Injection → Dependencies are injected.
3. Post-Processing (Before Initialization) → postProcessBeforeInitialization.
4. Initialization Callbacks:
o @PostConstruct.
o afterPropertiesSet (from InitializingBean).
5. Post-Processing (After Initialization) → postProcessAfterInitialization.
6. Usage → Bean is ready for use.
7. Destruction Callbacks:
o @PreDestroy.
o destroy (from DisposableBean).
Implementing BeanPostProcessorFactory and Its Role:

In the Spring Framework, the BeanPostProcessorFactory is not a standard concept or interface.


However, you can implement a custom factory-like pattern to register or create BeanPostProcessor
instances dynamically. Below, I explain the role of such a factory and how you can implement it.
Role of a BeanPostProcessorFactory
A factory for BeanPostProcessor can:
1. Encapsulate Creation Logic: Dynamically create or configure BeanPostProcessor instances
based on application requirements.
2. Centralize Configuration: Manage the lifecycle or dependencies of custom
BeanPostProcessor instances.
3. Enable Conditional Processing: Provide specific BeanPostProcessor implementations based
on conditions, like the active profile or environment.
Implementation Steps
Here’s how you could implement a BeanPostProcessorFactory:
1. Define the Factory Interface: Create an interface for the factory that can produce
BeanPostProcessor instances.

public interface BeanPostProcessorFactory {


BeanPostProcessor createBeanPostProcessor();
}
2. Implement the Factory: Provide a concrete implementation of the factory.

@Component
public class CustomBeanPostProcessorFactory implements BeanPostProcessorFactory {
@Override
public BeanPostProcessor createBeanPostProcessor() {
return new CustomBeanPostProcessor();
}
}
3. Register the BeanPostProcessor Dynamically: Use the factory in your application
configuration to register BeanPostProcessor instances.

@Configuration
public class BeanPostProcessorConfig {
@Bean
public BeanPostProcessor customBeanPostProcessor(BeanPostProcessorFactory factory) {
return factory.createBeanPostProcessor();
}
}

Example Usage
 The CustomBeanPostProcessor implementation from your code will be created and registered
using the factory.
 Spring will use this BeanPostProcessor during the initialization of beans.
When to Use a BeanPostProcessorFactory
 Dynamic Creation: If your application needs to dynamically decide the behavior or type of
BeanPostProcessor based on external factors like configuration or runtime conditions.
 Centralized Management: To ensure all BeanPostProcessor instances are created and
managed consistently.

You might also like