Translating now.

Here’s the English translation:


Have you ever come across @Configuration or @Bean while developing with Spring Boot? It’s also a common point of confusion: “How is this different from @Component?” or “Where should I actually use this?”

This article explains the roles and usage of @Configuration / @Bean, with concrete examples.


This article covers Java Configuration (defining Beans using @Configuration classes and @Bean methods). This is a different thing from the “application configuration values” you write in application.properties / application.yml, so if you’re looking for the configuration file side, please refer to that article instead.

After reading this article, you’ll be able to make the following judgments:

  • Whether to write with @Component or with @Configuration + @Bean
  • The standard pattern for using an external library’s class via DI
  • The behavioral differences that occur when you forget to add @Configuration, and how to avoid them

What is @Configuration?

@Configuration is an annotation that tells Spring “this class is a configuration class.” Inside a configuration class, you define @Bean methods to assemble the objects (Beans) you want to register with the Spring container.

Think of @Configuration as providing “a place where you write how to create Beans, all in one spot.”


What is @Bean?

@Bean is an annotation placed on a method, and it registers that method’s return value as a Bean in the Spring container. While @Component is “placed on a class, registering the class itself as a Bean,” the key difference with @Bean is that it “registers the object returned by a method as a Bean.”

Typical cases where @Bean shines:

  • When you want to register a class you didn’t write yourself (from an external library) as a Bean
  • When the creation process is somewhat complex and can’t be done with a simple new
  • When you want to combine configuration values or dependent Beans at creation time

Basic Usage (Example)

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 in the Spring container, allowing it to be injected into other classes.

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 the 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 Arguments in a @Bean Method (this is handy)

For a @Bean method, you just write the required Bean as an argument, and Spring resolves and passes it for you.

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. When you want to use values from application.yml as well, the pattern is the same: you receive a configuration class annotated with @ConfigurationProperties as an argument, and use its values to assemble the Bean. This is how Java Configuration and application configuration are linked together.

Changing the Scope (Only When Needed)

The default is singleton (one instance per application), but depending on the use case, you might 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, in typical business applications, singleton is used in the vast majority of cases.)


Points That Are Easy to Get Tripped Up On

1) Behavioral Differences Caused by @Configuration’s “Proxy”

A class annotated with @Configuration is internally proxied, which ensures that calls between @Bean methods return the “same Bean.” So, in code like the following, a() is not newed every time — instead, the same container-managed instance is basically returned.

@Configuration
public class AppConfig {

    @Bean
    public A a() {
        return new A();
    }

    @Bean
    public B b() {
        return new B(a()); // calling a()
    }
}

Conversely, if you don’t add @Configuration (or depending on the setup), this behavior can change and become a source of confusion. When starting out, it helps to remember: “if you’re writing a @Bean, lean toward using @Configuration” — this reduces the chance of trouble.

2) Can @Bean Be Used Without @Configuration?

The short answer is: yes, it can. However, there’s a precondition.

Precondition: The Class Itself Must Be Under Spring’s Management

A @Bean only has meaning when it’s written inside a “class that Spring picks up.” In other words, as long as the class itself is registered as a Bean, @Bean will work even without @Configuration, in situations such as:

  • The class has @Component on it
  • It’s component-scanned under @SpringBootApplication (or imported via @Import)
  • It’s explicitly loaded as Java Config

Example: @Bean also works with @Component.

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 gets registered as a Bean in the Spring container.

However, @Configuration Is Safer

When @Configuration is present, the configuration class enters “full mode” (CGLIB proxy), making it more likely that calls between @Bean methods return the same container-managed Bean.

Conversely, without @Configuration (e.g., with just @Component), calls between @Bean methods are treated as plain method calls, which can, depending on the situation, result in separate instances being created.

For this reason, if you’re writing something as a configuration class, it’s generally safer to add @Configuration as a rule.

3) Don’t Force Something That @Component Handles Fine into @Bean

Also, if you’d like to dig a bit deeper into the role of @Component on its own, check out What Is @Component in Spring Boot? Explaining the Difference from @Bean and How to Use It, which covers this including its relationship with constructor injection — worth a read alongside this article.

4) Know the Difference Between BeanFactory and ApplicationContext

An instance registered with @Bean is ultimately managed by the underlying container functionality called BeanFactory. ApplicationContext is an interface that extends BeanFactory, adding features like internationalization and event publishing, so in everyday development it’s enough to be aware of just the ApplicationContext side.

That said, when you use dynamic retrieval via getBean(), or more advanced techniques like rewriting Bean definitions afterward, knowing about BeanFactory makes it easier to understand what error messages mean.

If it’s your own class, the creation is simple, and it can normally be a component-scan target, then @Component / @Service / @Repository etc. are sufficient. @Bean is effective when “you can’t annotate the class” or “creation is somewhat special.”


Practical Rules for When You’re Unsure

Incidentally, “Aware” interfaces like BeanNameAware and ApplicationContextAware also come up frequently in situations involving a Bean’s lifecycle. For details on when to use these, see When Should You Use Spring Boot’s BeanNameAware and ApplicationContextAware? — worth checking if you’re unsure about designing your configuration classes.

When you’re torn between @Component and @Bean, the following gives a stable basis for deciding:

SituationRecommendationReason
You want to register your own class as-is@Component-familySimple and readable
You want to register an instance from an external library@Configuration + @BeanYou can’t annotate the class
Creation requires conditional branching or assembling configuration values@Configuration + @BeanInitialization logic can be made explicit
You want to define multiple instances of the same type and choose by purpose@Bean + @QualifierLets you select safely by name

Giving configuration classes the role of a “wiring diagram of dependent objects” makes the design easier to read.

Tips for Easier Swapping in Tests

@Bean definitions also pair well with swapping things out during testing. For example, if you turn an external API client into a Bean, it becomes easy to replace it with @TestConfiguration or @MockBean.

@TestConfiguration
public class TestClientConfig {
    @Bean
    public ApiClient apiClient() {
        return new ApiClient("http://localhost:9999");
    }
}

This allows safer switching between test and production than a design that directly news the production implementation.

Operational Considerations

  • When explicitly naming Beans, decide on a naming convention (e.g., xxxClient, xxxClock)
  • Don’t overuse conditional Beans (e.g., @ConditionalOnProperty)
  • Split configuration classes apart when the dependency graph becomes complex

Treating a configuration class as “a place to put anything” quickly makes it hard to read, so splitting by domain is effective.


Summary

  • @Configuration is “a configuration class where you write how Beans are created, all in one place”
  • @Bean “registers a method’s return value as a Bean in the Spring container”
  • @Bean is especially useful when you want to DI a class from an external library, or when creation is complex
  • @Bean can be used without @Configuration (though this assumes the class itself is under Spring’s management)
  • That said, if you’re writing it as a configuration class, operating with @Configuration attached is less prone to trouble