5 Ways to Register Beans in Spring: From @Configuration to FactoryBean
This article explains five different techniques for adding beans to the Spring IoC container—including @Configuration + @Bean, @ComponentScan, @Import with various selectors, FactoryBean, and BeanDefinitionRegistryPostProcessor—providing complete code examples and practical usage notes for developers.
Spring provides multiple mechanisms to register beans in its IoC container. This guide summarizes five common approaches with code examples.
1. @Configuration + @Bean
Declare a configuration class and define beans with @Bean methods.
@Configuration
public class MyConfiguration {
@Bean
public Person person() {
Person person = new Person();
person.setName("spring");
return person;
}
}2. @Component + @ComponentScan
Annotate component classes with @Component and enable scanning via @ComponentScan on a configuration class.
@Component
public class Person {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override
public String toString() { return "Person{" + "name='" + name + '\'' + '}'; }
}
@ComponentScan(basePackages = "com.springboot.initbean.*")
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = ctx.getBean(Person.class);
System.out.println(bean);
}
}Output:
Person{name='null'}3. @Import Annotation
@Import can bring additional classes or configurations into the container. It supports several variants.
3.1 Direct class import
@Import(Person.class)
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = ctx.getBean(Person.class);
System.out.println(bean);
}
}3.2 @Import + ImportSelector
@Import(MyImportSelector.class)
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = ctx.getBean(Person.class);
System.out.println(bean);
}
}
class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata metadata) {
return new String[]{"com.springboot.pojo.Person"};
}
}3.3 @Import + ImportBeanDefinitionRegistrar
@Import(MyImportBeanDefinitionRegistrar.class)
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = ctx.getBean(Person.class);
System.out.println(bean);
}
}
class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AbstractBeanDefinition bd = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition();
registry.registerBeanDefinition("person", bd);
}
}3.4 @Import + DeferredImportSelector
@Import(MyDeferredImportSelector.class)
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = ctx.getBean(Person.class);
System.out.println(bean);
}
}
class MyDeferredImportSelector implements DeferredImportSelector {
@Override
public String[] selectImports(AnnotationMetadata metadata) {
return new String[]{Person.class.getName()};
}
}4. Using FactoryBean Interface
Implement FactoryBean to create bean instances programmatically.
@Configuration
public class Demo1 {
@Bean
public PersonFactoryBean personFactoryBean() {
return new PersonFactoryBean();
}
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = ctx.getBean(Person.class);
System.out.println(bean);
}
}
class PersonFactoryBean implements FactoryBean<Person> {
@Override
public Person getObject() throws Exception { return new Person(); }
@Override
public Class<?> getObjectType() { return Person.class; }
}5. BeanDefinitionRegistryPostProcessor
Register bean definitions manually during container startup.
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.addBeanFactoryPostProcessor(new MyBeanDefinitionRegistryPostProcessor());
ctx.refresh();
Person bean = ctx.getBean(Person.class);
System.out.println(bean);
}
}
class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
AbstractBeanDefinition bd = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition();
registry.registerBeanDefinition("person", bd);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}
}Summary
@Configuration + @Bean
@ComponentScan + @Component
@Import with various selector interfaces
FactoryBean implementation
BeanDefinitionRegistryPostProcessor for manual registration
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
