LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 1018 min read

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?

Definition

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.

ReportGenerator.java
package com.programinds.demo;
import org.springframework.stereotype.Component;
@Component
public 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.

AppConfig.java
package com.programinds.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public ObjectMapperFacade objectMapperFacade() {
// custom construction logic that @Component alone couldn't express
return new ObjectMapperFacade(true, "yyyy-MM-dd");
}
}
Result

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.

Explicit bean names
@Component("primaryReportGenerator")
public class ReportGenerator {
// ...
}
@Configuration
public 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.

Different ways to retrieve beans
ApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
// By type — the most common and recommended approach
ReportGenerator generator = context.getBean(ReportGenerator.class);
// By explicit bean name
ReportGenerator 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"));
Console Output

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.

Listing all bean names
String[] beanNames = context.getBeanDefinitionNames();
for (String name : beanNames) {
System.out.println(name);
}
Example Output

Click Run to see what this code prints.

Common Mistakes

Avoid These 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.

Next Lesson →

Bean Scopes