CodeGym /Courses /Module 5. Spring /Annotations @Configuration and @Bean for Java-based confi...

Annotations @Configuration and @Bean for Java-based configuration

Module 5. Spring
Level 2 , Lesson 6
Available

Today we're focusing on configuring Spring applications. More specifically, how Java-based configuration with @Configuration and @Bean can replace XML files and make your life easier. Buckle up, this is gonna be fun!

Back in the "good old" days, Spring developers used XML files for configuration. It was... well, honestly, not great. Long XML files full of <bean> tags and other robotic stuff were more of a headache than a help.

Java-based configuration is like switching from messages in a bottle straight to email. It lets you:

  • Ditch XML: no need to jump between Java code and XML — all config lives right next to your code.
  • Make configuration strongly typed: you get compile-time benefits, and errors become obvious before runtime.
  • Improve convenience and readability: your teammates won't give you the side-eye when they see yet another XML file in the project.

Annotation @Configuration

The @Configuration annotation tells Spring that this class is a configuration class. It's like saying: "Hey Spring, here are the instructions for how to set up our beans — they're right here!"

Usage example


import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    // Here's where our bean configuration magic will be
}

Pretty simple, right? So what's next? We move on to @Bean, where the real magic starts.


Annotation @Bean

The @Bean annotation is used to explicitly define a bean in the Spring context. Essentially, it's a method that returns some object (your bean), and Spring takes care of managing its lifecycle.

Minimal example with @Bean

Let's create a simple bean that represents our core service:


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyService();
    }
}

class MyService {
    public void doSomething() {
        System.out.println("Working with MyService!");
    }
}

Now, when Spring brings up the context (for example, via ApplicationContext), it will automatically create an instance of MyService and manage it for you.


Using beans in the application

Okay, the bean is created. How do you use it? Easy! In Spring it's available for DI, for example:


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyController {

    private final MyService myService;

    @Autowired
    public MyController(MyService myService) {
        this.myService = myService;
    }

    public void process() {
        myService.doSomething();
    }
}

The MyService bean is auto-injected into the controller thanks to Spring magic. Nice, right?


Differences between @Component and @Bean

The key difference is where and how you define your bean:

  • @Component: use it when you want Spring to automatically find your class and register it as a bean. Good for standard cases with minimal customization.

  • @Bean: use it when you want to explicitly define how a bean is created and configured. Ideal when the bean requires complex creation logic or depends on third-party libraries.

Example for @Bean

Say you need to create a bean to configure a third-party HTTP client:


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import okhttp3.OkHttpClient;

@Configuration
public class HttpClientConfig {

    @Bean
    public OkHttpClient httpClient() {
        return new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .build();
    }
}

This is not something you can auto-scan with @Component, so using @Bean here is more appropriate.


Wiring beans: when one bean depends on another

Beans can depend on each other, and you can easily set that up with Java-based configuration. Imagine we have a UserService that depends on a UserRepository. Here's how it looks:


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public UserRepository userRepository() {
        return new UserRepository();
    }

    @Bean
    public UserService userService(UserRepository userRepository) {
        return new UserService(userRepository);
    }
}

class UserRepository {
    // Your repository code
}

class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void processUsers() {
        System.out.println("Working with users!");
    }
}

Spring will automatically pass the instance of UserRepository into the userService method, all thanks to IoC and DI. Convenient!


6. Advantages of Java-based configuration over XML

What? XML Java-based configuration
Readability Less readable syntax Code is intuitive
Typing No Full type support
Debugging Hard to find errors Errors are visible at compile time
Flexibility Limited by XML format Full control via Java code
Support Takes more time Faster thanks to IDEs

7. When to use @Bean?

Use @Bean when:

  • You need to create objects that are not your own classes (for example, third-party libraries).
  • You want to configure a bean using complex parameters.
  • You need explicit control over how a bean is created.

Common mistakes with @Configuration and @Bean

Any of us can make mistakes (even the most experienced dev). Here are some common pitfalls when working with Java-based configuration:

  • Forgot the @Configuration annotation: if you forget to mark the class as configuration, Spring won't know about your beans.
  • Type mismatches: make sure the return type of a method annotated with @Bean matches what you're expecting to inject.
  • Circular dependencies: if bean A depends on bean B and bean B depends on bean A, you'll hit an error. Think through your bean architecture in advance.

These mistakes are easy to avoid. All you need is practice and attention to detail!

Now you know how to use @Configuration and @Bean to configure your Spring apps. Stop typing XML and enjoy the perks of Java! Next we'll dive into practical aspects of building configuration classes and beans.

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION