DEV Community

Prabu Subra
Prabu Subra

Posted on • Updated on

Spring Beans Lifecycle

Spring IoC container create the beans and perform few post process activities based on the configurations like implementing Aware interfaces and annotations.
Spring Bean Lifecycle

In a nutshell, Spring IoC Container first check for dependency then calls its constructor. After creation of bean, it first injects the dependencies auto wired 0n constructor, Field and setters. Then Aware interfaces(BeanNameAware, BeanClassLoaderAware, ApplicationContextAware…) and annotated method like PostConstruct is invoked. At last init-method is invoked.

Main Method:-

public class Solution1 {
 public static void main(String[] args) {
  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SolutionConfig.class);
  Post post1 = context.getBean(Post.class);
  context.close();
 }
}
Enter fullscreen mode Exit fullscreen mode

Configuration file:-

@Configuration
public class SolutionConfig {

 @Bean
 public Author author() {
  return new Author("Aplha, Engineer", "alphaengineer@gmail.com");
 }

 @Bean
 public Post post() {
  return new Post("Spring Bean Lifecycle hooks", author());
 }
}
Enter fullscreen mode Exit fullscreen mode

Post class:-

@Getter
@Setter
@NoArgsConstructor
public class Post {

 private UUID id;
 private String content;
 private Author author;

 @Autowired
 public Post(String content, Author author) {
  System.out.println(" Author from Post constructor : "+author.toString());
  this.id = UUID.randomUUID();
  this.content = content;
  this.author = author;
 }
 public void setAuthor(Author author) {
  System.out.println(" setAuthor : "+author.toString());
  this.author = author;
 }
 @Override
 public String toString() {
  return "Post [id=" + id + ", content=" + content + ", author=" + author.toString() + "]";
 }
}
Enter fullscreen mode Exit fullscreen mode

Author Class:-

@Getter
@Setter
@NoArgsConstructor
public class Author {

 private UUID id;
 private String fullName;
 private String email;

 public Author(String fullName, String email) {
  System.out.println("Author constructor");
  this.id = UUID.randomUUID();
  this.fullName = fullName;
  this.email = email;
 }

 @Override
 public String toString() {
  return "Author [id=" + id + ", fullName=" + fullName + ", email=" + email + "]";
 }
}
Enter fullscreen mode Exit fullscreen mode

Sample Output:-

Author constructor
Author from Post constructor : Author [id=0b6afb4d-02d8-4f17-adfd-57aeafb8f206, fullName=Aplha, Engineer, email=alphaengineer@gmail.com]
Post : Post [id=4d5e403f-a75b-43f0-bf8f-d596a0e5814d, content=Spring Bean Lifecycle hooks, author=Author [id=0b6afb4d-02d8-4f17-adfd-57aeafb8f206, fullName=Aplha, Engineer, email=alphaengineer@gmail.com]]
Enter fullscreen mode Exit fullscreen mode

Dependencies are instantiated and injected based on Auto wiring configuration. if we use setter auto wiring then respective setter will called and add dependency.

Configuration:-

@Configuration
public class SolutionConfig {

 @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
 public Author author() {
  return new Author("Aplha, Engineer", "alphaengineer@gmail.com");
 }

 @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
 public Post post() {
  return new Post("Spring Bean Lifecycle hooks", author());
 }
}
Enter fullscreen mode Exit fullscreen mode

Aware Interfaces:-

Aware interfaces are used to check and configure information about bean name, class loader and Application Context details.

@Getter
@Setter
@NoArgsConstructor
public class Post implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, InitializingBean, DisposableBean {

 private UUID id;
 private String content;
 private Author author;

 public Post(String content, Author author) {
  System.out.println("Author from Post constructor : "+author.toString());
  this.id = UUID.randomUUID();
  this.content = content;
  this.author = author;
 }

 @PostConstruct
 public void init() {
  System.out.println("Post, @PostConstruct annotated method");
 }

 @PreDestroy
 public void predestroy() {
  System.out.println("Post, @PreDestroy annotated method");
 }

 public void initMethod() {
  System.out.println("Post, initMethod method");
 }
 public void destroyMethod() {
  System.out.println("Post, destroyMethod method");
 }

 public void destroy() {
  System.out.println("Post, destroy method from Disposable interface");
 }

 @Autowired
 public void setAuthor(Author author) {
  System.out.println("setAuthor : "+author.toString());
  this.author = author;
 }
 @Override
 public String toString() {
  return "Post [id=" + id + ", content=" + content + ", author=" + author.toString() + "]";
 }

 public void setBeanName(String name) {
  System.out.println("Post, setBeanName method from BeanNameAware interface : "+name);
 }

 public void setBeanClassLoader(ClassLoader classLoader) {
  System.out.println("Post, setBeanClassLoader method BeanClassLoaderAware interface : "+classLoader.getName());
 }

 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  System.out.println("Post, setApplicationContext method ApplicationContextAware interface : "+applicationContext.getApplicationName());
 }

 public void afterPropertiesSet() throws Exception {
  System.out.println("Post, afterPropertiesSet method InitializingBean interface  ");
 }
}
Enter fullscreen mode Exit fullscreen mode
@Getter
@Setter
@NoArgsConstructor
public class Author implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, InitializingBean, DisposableBean {

 private UUID id;
 private String fullName;
 private String email;

 public Author(String fullName, String email) {
  System.out.println("Author constructor");
  this.id = UUID.randomUUID();
  this.fullName = fullName;
  this.email = email;
 }
 @PostConstruct
 public void init() {
  System.out.println("Author, @PostConstruct annotated method");
 }
 @PreDestroy
 public void predestroy() {
  System.out.println("Author, @PreDestroy annotated method");
 }
 public void destroy() {
  System.out.println("Author, destroy method from DisposableBean interface");
 }
 public void initMethod() {
  System.out.println("Author, initMethod method");
 }
 public void destroyMethod() {
  System.out.println("Author, destroyMethod method");
 }
 @Override
 public String toString() {
  return "Author [id=" + id + ", fullName=" + fullName + ", email=" + email + "]";
 }
 public void setBeanName(String name) {
  System.out.println("Author, setBeanName method from BeanNameAware interface : "+name);
 }

 public void setBeanClassLoader(ClassLoader classLoader) {
  System.out.println("Author, setBeanClassLoader method BeanClassLoaderAware interface : "+classLoader.getName());
 }

 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  System.out.println("Author, setApplicationContext method ApplicationContextAware interface : "+applicationContext.getApplicationName());
 }
 public void afterPropertiesSet() throws Exception {
  System.out.println("Author, afterPropertiesSet method InitializingBean interface  ");
 }
}
Enter fullscreen mode Exit fullscreen mode

Sample Output:-

Author, setBeanClassLoader method BeanClassLoaderAware interface : app
Author, setApplicationContext method ApplicationContextAware interface : 
Author, @PostConstruct annotated method
Author, afterPropertiesSet method InitializingBean interface  
Author, initMethod method
Author from Post constructor : Author [id=1e360880-50eb-4bdf-a230-1e825ed67b39, fullName=Aplha, Engineer, email=alphaengineer@gmail.com]
setAuthor : Author [id=1e360880-50eb-4bdf-a230-1e825ed67b39, fullName=Aplha, Engineer, email=alphaengineer@gmail.com]
Post, setBeanName method from BeanNameAware interface : post
Post, setBeanClassLoader method BeanClassLoaderAware interface : app
Post, setApplicationContext method ApplicationContextAware interface : 
Post, @PostConstruct annotated method
Post, afterPropertiesSet method InitializingBean interface  
Post, initMethod method
Post : Post [id=ff29cc5a-b05c-448b-aa7d-05fbe17709ca, content=Spring Bean Lifecycle hooks, author=Author [id=1e360880-50eb-4bdf-a230-1e825ed67b39, fullName=Aplha, Engineer, email=alphaengineer@gmail.com]]
Post, @PreDestroy annotated method
Post, destroy method from Disposable interface
Post, destroyMethod method
Author, @PreDestroy annotated method
Author, destroy method from DisposableBean interface
Author, destroyMethod method
Enter fullscreen mode Exit fullscreen mode

Spring Bean Lifecycle Flow:-

Spring Lifecycle Flow

Spring IoC container first creates the depend beans, inject and then create the bean for usage, then delete the bean and its depend beans. if any runtime exceptions happen in any of these lifecycle hook methods. it breaks the bean instantiation. on successful execution of all these hooks spring bean is ready to use.

Thanks for spending your valuable time, Think blog is based on my understanding ony, if you feel anything is wrong please feel free to comment.

Reference:-
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/BeanFactory.html

Top comments (0)