Have you ever come across @Configuration or @Bean while developing with Spring Boot?
“How is it different from @Component?” “When is the right time to use it?” — these are points that can easily cause confusion.
In this article, we’ll explain the roles and usage of @Configuration / @Bean with concrete examples.
This article covers Java Configuration (the approach of defining Beans with @Configuration classes and @Bean methods). This is different from the ‘application configuration values’ written in application.properties / application.yml, so if you’re looking for the configuration file side, please refer to that article.
By reading this article, you’ll be able to make the following judgments:
- Whether to write something as
@Componentor as@Configuration+@Bean - The standard pattern for using classes from external libraries with DI
- The behavioral differences and workarounds for when you forget to add
@Configuration
What is @Configuration?
@Configuration is an annotation that tells Spring “this class is a configuration class.”
Within a configuration class, you define @Bean methods to assemble the objects (Beans) you want to register with the Spring container.
Conceptually, @Configuration provides “a place to consolidate how Beans are created.”
What is @Bean?
@Bean is an annotation that is attached to methods, and it registers the return value with the Spring container as a Bean.
While @Component is “attached to a class and registers the class itself as a Bean,” the major difference with @Bean is that it “registers the object returned by the method as a Bean.”
Typical cases where @Bean shines:
- You want to register a class that you didn’t create yourself (from an external library) as a Bean
- The creation process is a bit complex and can’t be done just with
new - You want to combine configuration values or dependent Beans during creation
Basic Usage (Sample)
For example, suppose you want to register the external library class Clock as a Bean. Since you can’t add @Component to the class, this is where @Bean comes in.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Clock;
@Configuration
public class AppConfig {
@Bean
public Clock clock() {
return Clock.systemDefaultZone();
}
}
This registers Clock with the Spring container, and other classes can inject it via DI.
import org.springframework.stereotype.Service;
import java.time.Clock;
@Service
public class TimeService {
private final Clock clock;
public TimeService(Clock clock) {
this.clock = clock;
}
}
Commonly Used Techniques
Specifying a Bean name
By default, the method name becomes the Bean name. If you want to specify it explicitly, you can do so as follows:
@Bean("systemClock")
public Clock clock() {
return Clock.systemDefaultZone();
}
Receiving dependencies as @Bean method arguments (this is convenient)
For @Bean methods, you can simply write the required Beans as arguments, and Spring will resolve and pass them.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyClient myClient(MyProperties props, Clock clock) {
return new MyClient(props.getEndpoint(), clock);
}
}
This is where the benefit of using @Configuration as “a place to assemble Beans” really shows.
Changing the scope (only when needed)
The default is singleton (one per application), but depending on the use case, you may use prototype or others.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
@Bean
@Scope("prototype")
public SomeObject someObject() {
return new SomeObject();
}
(That said, singleton is used in most ordinary business applications)
Common Pitfalls
1) Behavioral differences due to @Configuration’s “proxy”
Classes annotated with @Configuration are internally proxied so that calls between @Bean methods are adjusted to return “the same Bean.”
Therefore, in code like the following, a() is not newly instantiated each time — basically, the same container-managed instance is returned.
@Configuration
public class AppConfig {
@Bean
public A a() {
return new A();
}
@Bean
public B b() {
return new B(a()); // calling a()
}
}
Conversely, without @Configuration (or depending on configuration), this behavior changes and becomes a source of confusion.
At first, remembering “if you’re writing @Bean, stick with @Configuration” will reduce accidents.
2) Can @Bean be used without @Configuration?
To get to the point: yes, it can. However, there’s a prerequisite.
Prerequisite: The class itself must be under Spring’s management
@Bean only has meaning when written inside a “class that Spring picks up.”
In other words, if the class itself is registered as a Bean as follows, @Bean works even without @Configuration:
- It’s annotated with
@Component - It’s component-scanned under
@SpringBootApplication(or@Imported) - It’s explicitly loaded as Java Config
Example: @Bean works with @Component too.
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.time.Clock;
@Component
public class AppConfig {
@Bean
public Clock clock() {
return Clock.systemDefaultZone();
}
}
In this case too, Clock is registered as a Bean in the Spring container.
However, @Configuration is safer
With @Configuration, the configuration class becomes “full mode (CGLIB proxy),” and even when there are calls between @Bean methods, the same container-managed Bean is more likely to be returned.
Conversely, without @Configuration (e.g., with @Component), @Bean methods are treated as mere method calls, and depending on the situation, a separate instance may be created.
For that reason, if you’re writing it as a configuration class, adding @Configuration is generally the safer choice.
3) Don’t force @Bean for things that @Component can handle
If it’s your own class, the creation is simple, and it can be a normal component scan target, then @Component / @Service / @Repository is sufficient.
@Bean is effective when “you can’t add annotations to the class” or “the creation is a bit special.”
Practical Rules When You’re Unsure
Frequently Asked Questions (FAQ)
What’s the difference between @Configuration and @Component?
@Component is an annotation that “registers the class itself as a Bean” and makes it a target of Spring’s management. @Configuration is a special derivative of @Component that tells Spring “this is a configuration class with @Bean methods,” and it uses a CGLIB proxy to intercept method calls and control them to return the same Bean.
If you just want to register a Bean, use @Component; if you want a place to write the assembly steps for a Bean, use @Configuration — remembering it this way helps organize the distinction.
Which should I use, @Bean or @Component?
The basic distinction is: for your own classes where creation is simple, use @Component / @Service / @Repository; for instances from external libraries or those with complex creation steps, use @Configuration + @Bean.
What does “configuration” refer to in Spring Boot?
The query ‘Spring configuration’ is used in roughly two senses:
- Java Configuration (the topic of this page): The approach of defining Beans with
@Configurationclasses and@Beanmethods - Application configuration: Configuration values written in
application.properties/application.yml
The two are different but can work together. A typical pattern is having a @Bean method receive a configuration class annotated with @ConfigurationProperties as an argument, and assembling the Bean using values from application.yml.
Does @Bean work without @Configuration?
It works, but calls between @Bean methods are treated as ‘mere method calls,’ and depending on the situation, a separate instance may be created. If you’re writing it as a configuration class, the safe practice is to basically attach @Configuration (see ‘Common Pitfalls’ in the main text for details).
When you’re unsure about the boundary between @Component and @Bean, judging by the following keeps things stable.
| Situation | Recommended | Reason |
|---|---|---|
| Want to register your own class as-is | @Component family | Simple and readable |
| Want to register an instance from an external library | @Configuration + @Bean | Because you can’t add annotations to the class |
| Conditional branching or configuration value assembly is needed at creation | @Configuration + @Bean | Initialization logic can be made explicit |
| Want to define multiple Beans of the same type and use them for different purposes | @Bean + @Qualifier | Allows safe name-based selection |
If you give configuration classes the role of a “wiring diagram for dependency objects,” the design becomes easier to read.
Tips for Making Things Easy to Swap Out in Tests
@Bean definitions also work well for swapping things out during testing.
For example, if you make an external API client a Bean, it becomes easier to replace it with @TestConfiguration or @MockBean.
@TestConfiguration
public class TestClientConfig {
@Bean
public ApiClient apiClient() {
return new ApiClient("http://localhost:9999");
}
}
Compared to a design that directly news the production implementation, you can switch between test and production more safely.
Things to Be Careful About in Operations
- When specifying Bean names explicitly, decide on a naming convention (e.g.,
xxxClient,xxxClock) - Don’t overuse conditional Beans (
@ConditionalOnProperty, etc.) - When the dependency graph becomes complex, split the configuration classes
If you make configuration classes “a place to put anything,” they quickly become hard to read, so splitting them by domain is effective.
Summary
@Configurationis “a configuration class that consolidates how Beans are created”@Bean“registers the return value of a method as a Bean in the Spring container”@Beanis especially convenient when you want to inject (via DI) a class from an external library, or when creation is complex- @Bean can be used without @Configuration (but the class must be under Spring’s management as a prerequisite)
- However, if you’re writing it as a configuration class, adding @Configuration when operating it is less likely to cause accidents