Spring BootSpring Corebeginner
Updated:

Spring Beans: Definition, Creation and Wiring

6 min read

A Spring bean is just an object the container owns. This guide shows the two ways to define beans, how they get named and wired, and the stereotype annotations you will use daily.

TL;DR – Quick Answer

A Spring bean is simply an object that the Spring IoC container creates, wires and manages. You tell Spring which classes should become beans, either by annotating them with @Component (or a stereotype like @Service) so component scanning finds them, or by writing an @Bean method in a @Configuration class. The container then instantiates each bean, injects its dependencies, and hands it out wherever it is needed.

On This Page

Every Spring tutorial throws the word "bean" at you within the first minute, rarely stopping to say what one is. The definition is refreshingly simple: a bean is just an object that the Spring container owns instead of your code. The interesting part is how you tell Spring which objects should be beans, and how it names and wires them.

This page covers the two ways to define beans, the stereotype annotations you will use every day, and how the container connects beans together — the practical mechanics behind inversion of control.

A bean is a managed object

When the container starts, it does not manage every class in your project — only the ones you register. Those registered, container-built objects are beans. A bean is not a special type or a subclass of anything; a plain Java class becomes a bean purely because you asked Spring to manage it.

The container keeps one shared instance of each bean by default (singleton scope) and hands that same instance to everyone who needs it. This is why a @Service you write once is reused across every request without you creating it again. The different scopes are covered in Spring bean scopes.

Way one: @Component and component scanning

The most common way to define a bean is to annotate your class with @Component (or a stereotype) and let component scanning discover it.

import org.springframework.stereotype.Component;

@Component
public class PricingEngine {
    public double priceFor(String plan) {
        return switch (plan) {
            case "basic" -> 999;
            case "pro"   -> 2499;
            default      -> 0;
        };
    }
}

At startup Spring scans the packages under your main application class, finds every class carrying @Component (directly or through a stereotype), and registers each as a bean. The default bean name is the class name with a lowercase first letter — so PricingEngine becomes the bean pricingEngine. You did not write new PricingEngine() anywhere; the container did.

Component scanning is exactly what makes Spring Boot feel automatic. Boot sets the scan base package to your main class's package, which is why keeping your main class at the root of your package tree matters. The related annotations that drive Boot are collected in Spring Boot annotations.

Stereotype annotations: same bean, clearer intent

@Component works everywhere, but Spring offers specialised versions that also announce a class's role. They all create beans; they differ in meaning (and occasionally behaviour).

Annotation Use it on Extra meaning
@Component Any generic bean None — the plain base
@Service Business-logic classes Documents the service layer
@Repository Data-access classes Adds DB exception translation
@Controller Web MVC controllers Marks a request handler
@RestController REST endpoints @Controller + @ResponseBody

Choosing the right stereotype is not cosmetic. @Repository genuinely adds a behaviour — translating vendor-specific database exceptions into Spring's consistent DataAccessException hierarchy. And a reader skimming your code learns the architecture from the annotations alone.

Pro tip: When an interviewer asks "difference between @Component and @Service", the honest answer is "@Service is a @Component with a semantic role — technically they behave the same for bean creation, but @Repository actually adds exception translation." Naming that one real behavioural difference shows you know the framework, not just the labels.

Way two: @Bean methods in a @Configuration class

Sometimes the class you want as a bean is not yours to annotate — a library type, a third-party client, an object needing custom construction. For those, write an @Bean method inside a @Configuration class.

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

@Configuration
public class AppConfig {

    // The RestTemplate class comes from Spring — you can't put @Component on it,
    // so you register it with an @Bean method instead.
    @Bean
    public RestTemplate restTemplate() {
        RestTemplate template = new RestTemplate();
        template.setRequestFactory(customFactory());
        return template;
    }

    @Bean
    public PricingEngine premiumPricingEngine() {
        // full control over how this bean is built
        return new PricingEngine();
    }
}

Whatever the method returns becomes a bean, and the bean's name is the method name — restTemplate, premiumPricingEngine. This gives you full control over construction, which is why configuration classes are where you assemble third-party objects. The rule of thumb: @Component for classes you own, @Bean for objects you do not.

How beans get wired together

Defining beans is half the story; the container also connects them. When one bean needs another, you inject it, and Spring resolves the reference by type:

@Service
public class CheckoutService {
    private final PricingEngine pricingEngine;

    // Spring sees CheckoutService needs a PricingEngine bean and injects it
    public CheckoutService(PricingEngine pricingEngine) {
        this.pricingEngine = pricingEngine;
    }

    public double totalFor(String plan) {
        return pricingEngine.priceFor(plan);
    }
}

The container notices CheckoutService requires a PricingEngine, finds the bean it registered earlier, and passes it into the constructor. No lookup code, no new. The full set of injection styles — and why constructor injection wins — is in dependency injection in Spring, and the underlying principle in inversion of control.

Common mistake: Defining the same logical bean twice — once with @Component on the class and again with an @Bean method — then wondering why Spring complains about ambiguity or picks the "wrong" one. Register each bean once. If you need two variants, give them distinct names and use @Qualifier at the injection point.

Conditional and profile-based beans

Real applications often need different beans in different situations — a real email sender in production, a fake one in development. Spring lets you register beans conditionally, most commonly with profiles.

@Configuration
public class MailConfig {

    @Bean
    @Profile("prod")            // only becomes a bean when the "prod" profile is active
    public EmailSender smtpSender() {
        return new SmtpEmailSender();
    }

    @Bean
    @Profile("dev")             // active in development instead
    public EmailSender consoleSender() {
        return new ConsoleEmailSender();
    }
}

With the prod profile active the container registers smtpSender; with dev it registers consoleSender. Any class injecting EmailSender gets whichever one matches the environment, without a single if in your business code. This is the bean model showing its flexibility: which object satisfies a dependency can vary, while the code that depends on it never changes. Profiles are set through configuration such as application.properties.

Where beans physically live

It is worth being concrete about where beans exist at runtime. When the container starts, it builds each bean and stores it in an internal registry keyed by name and type. When a class needs a dependency, the container looks it up in that registry and injects the stored instance — which, for singletons, is the same object every time.

You can even reach into that registry directly, though you rarely should:

// Ask the container for a bean by type — useful for demos, not everyday code
PricingEngine engine = context.getBean(PricingEngine.class);

Reaching for getBean in application code is usually a sign you are fighting the framework; let injection supply your dependencies instead. But seeing it clarifies what the container is: a registry of managed objects you normally access through injection rather than lookup. This is the same registry the inversion of control container maintains on your behalf.

Beans have a lifecycle

A bean is not just created and forgotten. The container runs it through a defined sequence: instantiate, inject dependencies, run initialization callbacks, keep it alive for use, then run destruction callbacks at shutdown. You can hook into the init and destroy phases to open resources or clean them up. That whole sequence is covered in the Spring bean lifecycle.

Bringing it together

A Spring bean is an object the container creates, wires and manages — nothing more exotic than that. You define beans two ways: @Component (and its stereotypes @Service, @Repository, @Controller) for your own classes discovered by component scanning, and @Bean methods in a @Configuration class for objects you do not own. Spring names each bean, resolves dependencies between them by type, and hands out shared singletons by default.

Get comfortable defining beans both ways and explaining the stereotype differences, then move on through the Spring Boot learning hub to bean scopes and the lifecycle. Beans are the vocabulary of Spring — once you speak it fluently, the rest of the framework is just things you can do with beans.

Frequently Asked Questions

What is a Spring bean in simple terms?
A Spring bean is any object whose creation and lifecycle are managed by the Spring container instead of your own code. You mark a class or a factory method as a bean, and Spring builds it, injects its dependencies, and stores it for reuse. Most beans are singletons by default.
What is the difference between @Component and @Bean?
@Component goes on your own class and lets component scanning register it automatically as a bean. @Bean goes on a method inside a @Configuration class and registers whatever that method returns, which is ideal for third-party classes you cannot annotate. Use @Component for your code, @Bean for objects you do not own.
What are stereotype annotations in Spring?
Stereotype annotations are specialised forms of @Component that also describe a class's role: @Service for business logic, @Repository for data access, and @Controller or @RestController for web endpoints. They all create beans, but they document intent and, in the case of @Repository, add exception translation.
How does Spring name a bean?
By default the bean name is the class name with a lowercase first letter, so UserService becomes userService. For @Bean methods the bean name is the method name. You can override the name by passing a value, for example @Service("customName") or @Bean(name = "customName").
Are Spring beans singletons by default?
Yes. Unless you specify another scope, Spring creates one shared instance of each bean per container and reuses it everywhere. You can change this with @Scope, for example to prototype for a new instance on every request for the bean.

Want to Build Your Career in Java Full Stack with AI?

Join CodeBegun and train with working industry engineers — Explore the Program

Apply for Demo Class →
Siva Prasad Galaba
Founder, CodeBegun · Staff Engineer

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaches Java, Spring Boot and system design the way the industry actually works, and mentors students through projects, mock interviews and placement preparation.

Technically reviewed by CodeBegun Technical TeamLast reviewed 15 July 2026 LinkedIn
Chat with us