Engineering Full Stack Apps with Java and JavaScript
There are different ways to executing some code during initialization and destruction of a bean. We could do that using InitializingBean interface, but there are better approaches using annotations.
We will see two of such approaches here:
Using initMethod and destroyMethod attributes of the @Bean annotation
Advantage: We do not need source code access to component classes.
Limitation: We cannot specify methods that accept any parameters
Using PostConstruct and PreDestroy from javax.annotation package
Advantage: These are standard Java annotations
Limitation: We need to add annotations to the source code and hence need source code access
I will be using the same code from Bean scope example, but with some minor changes. I have done some cleanup and have added the new code that we will be using as comments. Will uncomment them while discussing the approaches.
JJWriter.java
package com.javajee.spring;
//import javax.annotation.PostConstruct;
//import javax.annotation.PreDestroy;class JJWriter {
private String content="default";
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
//@PostConstruct
public void initMethod() {
System.out.println("Init method called!");
}
//@PreDestroy
public void destroyMethod() {
System.out.println("Destroy method called!");
}
}
DemoConfig.java
I removed the @Scope("prototype") annotation, as with that annotation, the destroy may not be called.
package com.javajee.spring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class DemoConfig {@Bean (name = "jjwriter")
//@Bean (name = "jjwriter", initMethod="initMethod", destroyMethod="destroyMethod")
public JJWriter getJJWriter()
{
return new JJWriter();
}
}
JJWriterWithConfigMain.java
package com.javajee.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class JJWriterWithConfigMain {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(DemoConfig.class);
JJWriter writer1 = context.getBean("jjwriter", JJWriter.class);
System.out.println("new writer1 content="+writer1.getContent());
((AnnotationConfigApplicationContext)context).close();
}
}
Note: I am calling close method on the context in the end so that destroy method will be called.
We can use the initMethod and destroyMethod attributes of the @Bean annotation in our config class.
@Bean (name = "jjwriter", initMethod="initMethod", destroyMethod="destroyMethod")
public JJWriter getJJWriter()
{
return new JJWriter();
}
Now run the (modified) main method to verify the results.
A limitation of this approach is that we cannot specify methods that accept any parameters.
Remove the additional parameters for the @Bean.
Add @PostConstruct over the initMethod and @PreDestroy over the destroyMethod.
Run the (modified) main method to verify the results.
This method has the advantage that these are standard Java annotations.
Limitation of this approach is that we need to add annotations to the source code and hence need source code access.