Beans, Scopes & Configuration

Define beans explicitly with @Bean in @Configuration classes, control their lifetime with scopes (singleton vs prototype), and resolve ambiguity with @Qualifier and @Primary .

Learn Beans, Scopes & Configuration in our free Java course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…

Part of the free Java course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

Complete IoC Container & Dependency Injection first — you should already be comfortable with @Component and constructor injection.

💡 Analogy: A @Configuration class is a recipe book : each @Bean method is a recipe telling the kitchen (container) how to make one dish. Scope is the kitchen rule: a singleton dish is cooked once and shared at a buffet; a prototype dish is freshly cooked for every order. When two cooks could make the same dish, @Primary picks the house default and @Qualifier names a specific cook.

You describe the recipes and rules; the container does the cooking and serving.

A method annotated @Bean inside a @Configuration class registers its return value as a managed bean. This is how you create beans for types you don't own and can't annotate.

The default singleton scope gives one shared instance per container — perfect for stateless services. Prototype gives a fresh instance on every request. Web apps add request and session scopes.

When several beans match a type, Spring needs help. @Primary marks one as the default; @Qualifier("name") selects a specific bean at the injection point and overrides @Primary there.

To make scope concrete, here is the shared-instance vs new-instance distinction done by hand, with real output.

Answer: for types you don't own / can't annotate, or when you need custom construction logic.

Answer: singleton — one shared instance per container.

Answer: an explicit @Qualifier at that injection point overrides @Primary .

You can now declare beans explicitly with @Bean in @Configuration classes, choose the right scope (singleton vs prototype, plus web scopes), and resolve ambiguous dependencies with @Primary and @Qualifier.

Next up: Building REST Controllers — exposing your beans over HTTP with @RestController.

Practice quiz

What does a @Bean method do?

  • Deletes a bean
  • Explicitly defines a bean whose return value the container manages
  • Marks a field final
  • Starts the server

Answer: Explicitly defines a bean whose return value the container manages. A method annotated @Bean produces an object that Spring registers and manages as a bean — useful for types you can't annotate.

Where do @Bean methods normally live?

  • In a class annotated @Configuration
  • In a controller
  • In application.properties
  • In the pom.xml

Answer: In a class annotated @Configuration. @Bean methods are declared inside @Configuration classes, which act as a source of bean definitions.

What is the DEFAULT scope of a Spring bean?

  • prototype
  • request
  • session
  • singleton

Answer: singleton. By default a bean is singleton-scoped: one shared instance is created per Spring container.

How does 'prototype' scope differ from 'singleton'?

  • Prototype creates a new instance every time the bean is requested
  • Prototype is faster
  • Prototype is read-only
  • There is no difference

Answer: Prototype creates a new instance every time the bean is requested. A prototype-scoped bean yields a fresh instance on each request/injection, rather than sharing one.

When two beans match a dependency, what does @Primary do?

  • Throws an error
  • Marks one bean as the default choice when several qualify
  • Deletes the others
  • Renames the bean

Answer: Marks one bean as the default choice when several qualify. @Primary designates a preferred bean so injection succeeds without ambiguity when multiple candidates exist.

What is @Qualifier used for?

  • To name a bean and select it by name at the injection point
  • To make a bean lazy
  • To delete a bean
  • To set the port

Answer: To name a bean and select it by name at the injection point. @Qualifier selects a specific bean by name when more than one candidate of a type exists.

Why use @Bean instead of @Component sometimes?

  • @Bean is faster
  • To register types you don't own / can't annotate (e.g. library classes)
  • @Component is deprecated
  • @Bean works only in tests

Answer: To register types you don't own / can't annotate (e.g. library classes). @Bean lets you define beans for third-party classes you cannot annotate, with full control over construction.

Which scopes are web-aware (only valid in a web application)?

  • singleton and prototype
  • request and session
  • static and final
  • public and private

Answer: request and session. request and session scopes are web-aware: a bean per HTTP request or per HTTP session respectively.

If both @Primary and @Qualifier could apply, which wins at an injection point using @Qualifier?

  • @Primary always wins
  • Neither — it errors
  • @Qualifier wins for that specific injection point
  • It is random

Answer: @Qualifier wins for that specific injection point. An explicit @Qualifier at the injection point takes precedence over @Primary for that point.

What annotation sets a non-default scope on a bean?

  • @Scope("prototype")
  • @Lazy
  • @Order
  • @Profile

Answer: @Scope("prototype"). @Scope, e.g. @Scope("prototype"), overrides the default singleton scope for that bean.