Configuration and Bean Methods

@Configuration and @Bean

You cannot put @Component on a class you did not write (a library class such as Clock or RestClient). Instead, write a method that creates the object and annotate it with @Bean inside a @Configuration class. Spring calls the method once and registers the result as a bean.

package com.shopease.config;

import java.time.Clock;
import java.time.ZoneId;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean                              // bean name = method name: "clock"
    public Clock clock() {
        return Clock.system(ZoneId.of("Asia/Kolkata"));
    }

    @Bean
    public PaymentGateway paymentGateway() {
        return new RazorpayGateway("rzp_test_key");   // we choose the implementation here
    }
}

Using the Beans

@Service
public class OrderService {
    private final PaymentGateway gateway;
    private final Clock clock;

    public OrderService(PaymentGateway gateway, Clock clock) {   // both injected
        this.gateway = gateway;
        this.clock = clock;
    }

    public String placeOrder(long orderId, int amount) {
        return gateway.charge(orderId, amount) + " at " + LocalDateTime.now(clock);
    }
}

Tip: Injecting a Clock instead of calling LocalDateTime.now() directly lets tests use Clock.fixed(...) and get the same time on every run.

@Component vs @Bean

@Component (and @Service ...)@Bean
Whereon the classon a method in a @Configuration class
Who creates the objectSpring calls the constructoryour method creates it
Use foryour own classeslibrary classes, or when creation needs logic