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.
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();
}
}
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());
}
}
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() + "]";
}
}
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 + "]";
}
}
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]]
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());
}
}
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 ");
}
}
@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 ");
}
}
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
Spring Bean 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, if you feel any other details has to be added/removed, please feel free to comment.
Reference:- https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/BeanFactory.html
Subscribe to my newsletter
Read articles from Prabu Subra directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Prabu Subra
Prabu Subra
Programming, Running, Badminton