Spring Beans
Understand what a "bean" is in Spring, the different ways beans get registered with the container, and how to retrieve them.
Introduction
You have used the word "bean" throughout this course without a formal definition. This lesson closes that gap: what a bean actually is, the two main ways to register one, how to give it an explicit name, and the different ways to pull a bean back out of the container.
What Exactly Is a Bean?
A Spring bean is simply an object that is instantiated, assembled, and managed by the Spring IoC container. It is not a special kind of class — any plain Java object becomes a "bean" the moment the container takes responsibility for creating and wiring it.
There are two mainstream ways to tell Spring "please manage this object as a bean": annotate the class itself with a stereotype annotation like @Component, or explicitly declare a method that returns the object, annotated with @Bean.
Registering Beans with @Component
This is the approach used throughout this course so far. You annotate a class you own with @Component (or a more specific stereotype like @Service, @Repository, or @Controller), and @ComponentScan discovers it automatically.
package com.programinds.demo;
import org.springframework.stereotype.Component;
@Componentpublic class ReportGenerator {
public String generate(String title) { return "Report: " + title; }}Registering Beans with @Bean
Sometimes you need to register an object you do not own the source code for (a third-party library class), or one that needs custom construction logic. For those cases, use @Bean inside a @Configuration class instead.
package com.programinds.demo;
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;
@Configurationpublic class AppConfig {
@Bean public ObjectMapperFacade objectMapperFacade() { // custom construction logic that @Component alone couldn't express return new ObjectMapperFacade(true, "yyyy-MM-dd"); }}Click Run to see what this code prints.
Naming a Bean
By default, a bean's name is derived from the class name (with a lowercase first letter) for @Component, or the method name for @Bean. You can override this explicitly when needed.
@Component("primaryReportGenerator")public class ReportGenerator { // ...}
@Configurationpublic class AppConfig {
@Bean(name = "jsonMapper") public ObjectMapperFacade objectMapperFacade() { return new ObjectMapperFacade(true, "yyyy-MM-dd"); }}Retrieving Beans from the Container
You have already used getBean(Class) to retrieve a bean by type. Spring also supports retrieving by name, or by both name and type together.
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// By type — the most common and recommended approachReportGenerator generator = context.getBean(ReportGenerator.class);
// By explicit bean nameReportGenerator named = (ReportGenerator) context.getBean("primaryReportGenerator");
// By name and type together (avoids a manual cast)ReportGenerator namedTyped = context.getBean("primaryReportGenerator", ReportGenerator.class);
System.out.println(generator.generate("Q3 Sales"));Click Run to see what this code prints.
Inspecting the Container
For debugging, ApplicationContext exposes methods to list every registered bean name, which is useful when tracking down configuration issues.
String[] beanNames = context.getBeanDefinitionNames();for (String name : beanNames) { System.out.println(name);}Click Run to see what this code prints.
Common Mistakes
- Calling getBean() repeatedly inside business logic instead of relying on Dependency Injection to supply beans automatically.
- Registering the same conceptual object with both @Component and a separate @Bean method, causing a naming conflict.
- Forgetting that @Bean methods only take effect inside classes annotated with @Configuration.
Best Practices
- Use @Component for classes you own; use @Bean for third-party classes or objects needing custom construction.
- Reserve manual getBean() calls for your application's composition root (like MainApp); let injection handle the rest.
- Give beans explicit names only when you genuinely need to distinguish between multiple beans of the same type.
Frequently Asked Questions
No. Only objects the container is told to manage (via @Component, @Bean, or similar) are beans; plain objects you create with "new" inside your own code are not.
No, bean names must be unique within the container; a naming collision causes a startup error.
Singleton — the container creates exactly one shared instance by default, though other scopes are available, which we cover in the next lesson.
Key Takeaways
- A bean is any object created and managed by the Spring IoC container.
- @Component (and its specializations) registers classes you own; @Bean registers objects via factory methods, often for third-party classes.
- Beans can be retrieved by type, by name, or by both, though direct DI is preferred over manual getBean() calls.
- ApplicationContext can list all registered bean names, which is useful for debugging.
Summary
A bean is nothing more than a container-managed object — but how it is created, named, and shared has real consequences for your application's behavior. That naturally raises the question of how many instances of a bean actually exist, which is exactly what bean scopes control. We will explore that next.