This is a self-contained running example including/showcasing: minimum dependencies needed, Java Configuration, Bean declaration by annotation and Java Configuration, Dependency Injection by Constructor and by Property, and Pre/Post hooks.
These dependencies are needed in the classpath:
Starting from the end, this is our Main class that serves as a placeholder for the main()
method which initialises the Application Context by pointing to the Configuration class and loads all the various beans needed to showcase particular functionality.
package com.stackoverflow.documentation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
//initializing the Application Context once per application.
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(AppConfig.class);
//bean registered by annotation
BeanDeclaredByAnnotation beanDeclaredByAnnotation =
applicationContext.getBean(BeanDeclaredByAnnotation.class);
beanDeclaredByAnnotation.sayHello();
//bean registered by Java configuration file
BeanDeclaredInAppConfig beanDeclaredInAppConfig =
applicationContext.getBean(BeanDeclaredInAppConfig.class);
beanDeclaredInAppConfig.sayHello();
//showcasing constructor injection
BeanConstructorInjection beanConstructorInjection =
applicationContext.getBean(BeanConstructorInjection.class);
beanConstructorInjection.sayHello();
//showcasing property injection
BeanPropertyInjection beanPropertyInjection =
applicationContext.getBean(BeanPropertyInjection.class);
beanPropertyInjection.sayHello();
//showcasing PreConstruct / PostDestroy hooks
BeanPostConstructPreDestroy beanPostConstructPreDestroy =
applicationContext.getBean(BeanPostConstructPreDestroy.class);
beanPostConstructPreDestroy.sayHello();
}
}
The configuration class is annotated by @Configuration
and is used as a parameter in the initialised Application Context. The @ComponentScan
annotation at the class level of the configuration class points to a package to be scanned for Beans and dependencies registered using annotations. Finally the @Bean
annotation serves as a bean definition in the configuration class.
package com.stackoverflow.documentation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.stackoverflow.documentation")
public class AppConfig {
@Bean
public BeanDeclaredInAppConfig beanDeclaredInAppConfig() {
return new BeanDeclaredInAppConfig();
}
}
The @Component
annotation serves to demarcate the POJO as a Spring bean available for registration during component scanning.
@Component
public class BeanDeclaredByAnnotation {
public void sayHello() {
System.out.println("Hello, World from BeanDeclaredByAnnotation !");
}
}
Notice that we don't need to annotate or otherwise mark our POJO since the bean declaration/definition is happening in the Application Configuration class file.
public class BeanDeclaredInAppConfig {
public void sayHello() {
System.out.println("Hello, World from BeanDeclaredInAppConfig !");
}
}
Notice that the @Autowired
annotation is set at the constructor level. Also notice that unless explicitely defined by name the default autowiring is happening based on the type of the bean (in this instance BeanToBeInjected
).
package com.stackoverflow.documentation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class BeanConstructorInjection {
private BeanToBeInjected dependency;
@Autowired
public BeanConstructorInjection(BeanToBeInjected dependency) {
this.dependency = dependency;
}
public void sayHello() {
System.out.print("Hello, World from BeanConstructorInjection with dependency: ");
dependency.sayHello();
}
}
Notice that the @Autowired
annotation demarcates the setter method whose name follows the JavaBeans standard.
package com.stackoverflow.documentation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class BeanPropertyInjection {
private BeanToBeInjected dependency;
@Autowired
public void setBeanToBeInjected(BeanToBeInjected beanToBeInjected) {
this.dependency = beanToBeInjected;
}
public void sayHello() {
System.out.println("Hello, World from BeanPropertyInjection !");
}
}
We can intercept initialisation and destruction of a Bean by the @PostConstruct
and @PreDestroy
hooks.
package com.stackoverflow.documentation;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class BeanPostConstructPreDestroy {
@PostConstruct
public void pre() {
System.out.println("BeanPostConstructPreDestroy - PostConstruct");
}
public void sayHello() {
System.out.println(" Hello World, BeanPostConstructPreDestroy !");
}
@PreDestroy
public void post() {
System.out.println("BeanPostConstructPreDestroy - PreDestroy");
}
}