skip to content

Dependency Injection

How Spring decides what to inject: injection styles, @Autowired resolution, disambiguation with @Qualifier and @Primary, the JSR-330 annotations, and collection or provider injection. The most-asked corner of the container, because every real application eventually hits an ambiguous type.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

29

What does @Autowired do, and what does it mean that Spring resolves it "by type"?

level: juniorimportance: must knowfreq 90%

answer

  1. inject by declared type
  2. interface param -> impl bean
  3. constructor > setter > field
  4. single constructor = annotation optional (4.3+)
  5. one candidate needed

basics

~10 s

@Autowired tells Spring to inject a dependency automatically. "By type" means Spring looks in its container for a bean whose type matches the field, constructor parameter, or setter parameter, and wires that bean in.

solid answer

~40 s

@Autowired marks an injection point — a constructor, setter, or field — that the Spring container should fill from its own beans. Resolution is primarily by type: Spring finds a bean assignable to the required type and injects it. It works with the declared type, so an interface parameter matches whichever bean implements it. Constructor injection is preferred (and since Spring 4.3 a single constructor is autowired without the annotation). If exactly one candidate matches, injection succeeds. Zero matching candidates or more than one both cause problems — a missing required bean fails startup, and multiple candidates are ambiguous unless narrowed. @Autowired is handled by an infrastructure bean post-processor, not by reflection you write yourself, so it happens automatically during bean creation.

code

java · 17 lines
java
public interface GreetingService { String greet(String name); }

@Service
class EnglishGreetingService implements GreetingService {
    public String greet(String name) { return "Hello, " + name; }
}

@Service
class Welcomer {
    private final GreetingService greetingService;

    // Single constructor -> @Autowired optional since Spring 4.3.
    // Resolved by type: the one GreetingService bean is injected.
    Welcomer(GreetingService greetingService) {
        this.greetingService = greetingService;
    }
}

go deeper

for a junior

Know it injects a matching bean by type and prefer constructor injection.

for a middle

Explain the single-constructor 4.3 rule and interface-to-impl matching.

for a senior

Tie 'by type' to the container search and name the two failure exceptions.

for a principal

Frame @Autowired as declarative wiring handled by an infrastructure post-processor and reason about type/generics matching.

### What @Autowired is `@Autowired` (package `org.springframework.beans.factory.annotation`) marks an **injection point** where the Spring IoC container should supply a collaborating bean. You can put it on a **constructor**, a **setter (or any method)**, or a **field**. It is Spring's own annotation (distinct from JSR-330 `@Inject`, covered by a sibling topic). ### "By type" resolution When Spring creates a bean, for each `@Autowired` point it takes the **declared type** of the target (field type / parameter type) and searches the `ApplicationContext` for a bean **assignable** to that type. Because it matches by type, you normally autowire an **interface** and Spring injects whatever concrete bean implements it: ```java @Autowired PaymentGateway gateway; // matches the single PaymentGateway bean ``` If the container holds exactly one bean of that type, it is injected. Generics are respected too: `@Autowired Repository<Order>` will not match `Repository<Customer>`. ### Constructor vs setter vs field - **Constructor injection** is recommended: dependencies are final, the object is fully initialized, and it is testable without Spring. Since **Spring 4.3**, if a class has a **single constructor**, `@Autowired` is optional there. - **Setter / method injection** allows optional or reconfigurable dependencies. - **Field injection** is concise but discouraged (hard to test, hides required deps). ### Who performs it You don't call anything. The infrastructure bean `AutowiredAnnotationBeanPostProcessor` scans each bean during creation and fills the injection points. It is registered automatically by `<context:annotation-config>`, component scanning, or a Spring Boot auto-config. ### The two failure modes - **No candidate**: a required `@Autowired` with zero matching beans fails **at startup** with `NoSuchBeanDefinitionException`. - **Multiple candidates**: two+ beans of the type are **ambiguous**; without a tie-breaker Spring throws `NoUniqueBeanDefinitionException`. ### When to use Use `@Autowired` (via constructor) for required collaborators between your own beans. It keeps wiring declarative rather than manual `new`.

  • Where can you put @Autowired?
    On a constructor, on a setter or any config method, or directly on a field. Constructor injection is preferred; field injection is discouraged because it hides dependencies and hampers testing.
  • Do you still need @Autowired on a constructor?
    Not if the class has exactly one constructor — since Spring 4.3 Spring autowires the sole constructor implicitly. With multiple constructors you must annotate one to pick it.

saying these in an interview costs you the question

  • Thinking @Autowired matches by field/bean name first rather than by type
  • Believing you must always write @Autowired on every constructor
  • Claiming @Autowired works via your own reflection code rather than a bean post-processor

context

open as a page

What problem does method injection (@Lookup / lookup-method) solve when a singleton bean depends on a prototype bean?

level: juniorimportance: must knowfreq 62%

basics

~10 s

A singleton is created once, so a prototype injected normally is captured only once and reused forever. Method injection lets the singleton ask the container for a fresh prototype on every call.

open as a page

How do you inject a dependency into a Spring bean that may not exist in the context, without the application failing to start?

level: juniorimportance: must knowfreq 62%

basics

~10 s

Make the dependency optional. Use Optional<T>, or @Autowired(required=false), or ObjectProvider<T>. If no bean exists Spring injects an empty Optional / null / an empty provider instead of throwing NoSuchBeanDefinitionException.

open as a page

What does @Primary do, and when would you reach for it?

level: juniorimportance: must knowfreq 78%

basics

~20 s

@Primary marks one bean as the default choice when several beans of the same type exist. If an injection point doesn't say which one it wants, Spring picks the @Primary one instead of throwing an error.

open as a page

What is the difference in default injection semantics between @Resource and @Autowired?

level: juniorimportance: must knowfreq 75%

basics

~10 s

@Autowired matches a bean by its type first. @Resource (from jakarta.annotation) matches by name first, defaulting to the field or setter property name.

open as a page

What are the three styles of dependency injection in Spring, and how does each supply a bean its collaborators?

level: juniorimportance: must knowfreq 85%

basics

~10 s

Constructor injection passes dependencies as constructor arguments. Setter injection calls setter methods after construction. Field injection sets private fields directly (via reflection), usually with @Autowired on the field.

open as a page

What does required=true vs required=false on @Autowired mean, and how else can you model an optional dependency?

level: middleimportance: must knowfreq 75%

basics

~20 s

required=true (the default) means the bean must exist or startup fails. required=false means Spring skips injection and leaves the field null if no matching bean is found. You can also declare the dependency as Optional<T> or use @Nullable.

open as a page

How does the @Lookup annotation work, and what are the requirements on the method and bean it is used on?

level: middleimportance: must knowfreq 55%

basics

~10 s

You annotate a method (usually abstract) with @Lookup. Spring generates a CGLIB subclass that overrides it to return a fresh bean from the container each call. The class and method can't be final/private/static.

open as a page

How do you inject all beans of a given type at once, and what do you get when you use List, Set, or Map<String,T>?

level: middleimportance: must knowfreq 58%

basics

~20 s

Autowire a List<T>, Set<T>, or Map<String,T>. Spring injects every bean of type T. For the Map the keys are the bean names and the values are the beans. This is the standard way to implement plugin/strategy registries.

open as a page

How does @Qualifier select a specific bean, and what is bean-name fallback matching?

level: middleimportance: must knowfreq 74%

basics

~20 s

@Qualifier("name") tells Spring exactly which bean to inject when several match by type. If no bean carries that qualifier value, Spring falls back to matching the value against bean names — so @Qualifier can also target a bean by its id.

open as a page

Why does the Spring team recommend constructor injection over field injection for required dependencies?

level: middleimportance: must knowfreq 80%

basics

~10 s

Constructor injection guarantees required dependencies exist at creation, lets fields be final (immutable), makes dependencies explicit, and lets you build the object in tests with plain new — no Spring or reflection needed.

open as a page

Walk through the resolution order Spring uses for a single-valued @Autowired point, and when NoSuchBeanDefinitionException vs NoUniqueBeanDefinitionException is thrown.

level: seniorimportance: must knowfreq 70%

basics

~20 s

Spring first collects all beans assignable to the required type. Zero candidates and required -> NoSuchBeanDefinitionException. One candidate -> inject it. Many candidates -> narrow by @Primary, then @Qualifier, then by matching the field/parameter name; if still not unique -> NoUniqueBeanDefinitionException.

open as a page

When you inject a List<T> of beans, how do you control their order, and how do @Order, the Ordered interface, and orderedStream() relate?

level: middleimportance: should knowfreq 45%

basics

~20 s

Add @Order(n) to each bean or implement Ordered.getOrder(). Spring sorts injected List/Set/array by that value — lower number = higher priority = earlier. For ObjectProvider use orderedStream(), which applies the same ranking; plain stream() does not.

open as a page

How does Spring map the JSR-330 annotations @Inject and @Named onto its own DI model?

level: middleimportance: should knowfreq 50%

basics

~10 s

Spring treats @Inject (jakarta.inject.Inject) like @Autowired — by-type injection — and @Named like @Qualifier or @Component's bean name. You need the jakarta.inject dependency on the classpath.

open as a page

Which component processes @Autowired, and at what point in the bean lifecycle does constructor vs field/setter injection happen?

level: seniorimportance: should knowfreq 55%

basics

~10 s

AutowiredAnnotationBeanPostProcessor handles @Autowired (and @Value and @Inject). Constructor injection is resolved when the bean is instantiated; field and setter injection happen afterward during the property-population phase, before initialization callbacks.

open as a page

When would you choose @Lookup / lookup-method over ObjectFactory/Provider (and vice versa) for obtaining prototype beans?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Both give a singleton fresh prototypes. @Lookup keeps a clean method call but needs CGLIB and non-final abstract-ish methods. ObjectFactory/Provider is a plain injected field with getObject()/get() — no CGLIB, easier to test, usually preferred today.

open as a page

Contrast XML <lookup-method> and <replaced-method>. What is the MethodReplacer interface and how do they relate to CGLIB?

level: seniorimportance: should knowfreq 34%

basics

~10 s

<lookup-method> makes Spring override a method to return a named bean each call — the XML form of @Lookup. <replaced-method> swaps a method's whole implementation with a MethodReplacer bean. Both use CGLIB subclassing.

open as a page

What is ObjectProvider<T> and how do getIfAvailable(), getIfUnique(), getObject(), and stream() differ? When would you choose it over plain or Optional injection?

level: seniorimportance: should knowfreq 48%

basics

~20 s

ObjectProvider<T> is a lazy handle to a bean. getObject() throws if none/multiple; getIfAvailable() returns null if none (throws if multiple); getIfUnique() returns null if none OR multiple non-primary; stream()/orderedStream() give all matches. Use it for optional, ambiguous, lazy, or prototype lookups.

open as a page

How do you create and use a custom qualifier annotation, and why prefer it over @Qualifier("string")?

level: seniorimportance: should knowfreq 46%

basics

~20 s

Define your own annotation meta-annotated with @Qualifier, e.g. @Fast. Put it on the bean and on the injection point. Spring matches them like a typed qualifier. It's refactor-safe and typo-proof, unlike a plain @Qualifier("fast") string.

open as a page

Walk through Spring's full candidate-resolution algorithm when multiple beans match an injection point.

level: seniorimportance: should knowfreq 52%

basics

~20 s

Spring collects all beans of the required type. It filters by @Qualifier, then prefers a @Primary bean, then the highest @Priority, then a bean whose name matches the injection point. If none of those uniquely picks one, it throws NoUniqueBeanDefinitionException.

open as a page

What problems does JSR-330 Provider<T> solve, and how does Spring implement it?

level: seniorimportance: should knowfreq 40%

basics

~10 s

Provider<T> gives lazy, on-demand access to a bean via provider.get() instead of injecting the instance eagerly. It helps with optional beans, prototype-scoped beans in singletons, and breaking circular dependencies.

open as a page

How do you model optional dependencies and disambiguate multiple constructors across the three injection styles?

level: seniorimportance: should knowfreq 45%

basics

~10 s

Optional deps: setter with @Autowired(required=false), or constructor param typed Optional<T> or annotated @Nullable. Multiple constructors: mark the one to use with @Autowired (single-ctor auto-wiring only works when there's exactly one).

open as a page

Explain the testability and immutability implications of choosing constructor versus field injection.

level: seniorimportance: should knowfreq 60%

basics

~10 s

Constructor injection lets fields be final (immutable, thread-safe) and lets tests build the object with new passing mocks. Field injection forbids final and forces tests to use reflection or a Spring context.

open as a page

What happens when @Value is placed on an injection point (or alongside @Autowired), and how does that interact with by-type autowiring?

level: principalimportance: should knowfreq 40%

basics

~20 s

@Value tells Spring to inject a resolved value (from a property or expression) instead of looking up a bean by type. It's handled by the same processor as @Autowired, and when @Value supplies a value that value wins — no by-type bean lookup occurs for that point.

open as a page

Because method injection relies on CGLIB subclassing, what constraints and failure modes must you anticipate, and how do you diagnose 'my @Lookup returns the same instance'?

level: principalimportance: should knowfreq 26%

basics

~20 s

CGLIB subclasses the bean, so it can't be final, the method can't be final/private/static, and the bean must be instantiable (not from a @Bean factory method). If none of that holds, Spring can't override the method and you get the original body / a stale singleton.

open as a page

What does @Lazy do when placed on an injection point (not a bean definition), and how does the resulting proxy behave? When is it the right tool?

level: principalimportance: should knowfreq 34%

basics

~20 s

@Lazy on an injection point injects a lazy-resolution proxy instead of the real bean. Spring resolves the actual bean only on the first method call through the proxy. It's used to break circular dependencies, defer expensive initialization, or inject a shorter-scoped bean.

open as a page

What is @Fallback (Spring 6.2), how does it differ from @Primary, and when would a library use it?

level: principalimportance: nice to knowfreq 20%

basics

~20 s

@Fallback (Spring 6.2) marks a bean as a last-resort candidate: it's used only when no regular bean of that type exists. It's the opposite of @Primary — @Primary says 'prefer me', @Fallback says 'use me only if there's nothing else'.

open as a page

Which BeanPostProcessors handle @Autowired, @Resource, and @Inject, and how do their qualifier/name semantics interact when multiple candidates exist?

level: principalimportance: nice to knowfreq 22%

basics

~10 s

AutowiredAnnotationBeanPostProcessor handles @Autowired and @Inject (by type, with @Qualifier/@Named narrowing). CommonAnnotationBeanPostProcessor handles @Resource (by name first, type fallback). Both are registered by default in Spring.

open as a page

How does the injection style you choose affect circular dependencies and proxy-based features like @Transactional?

level: principalimportance: nice to knowfreq 35%

basics

~20 s

Constructor injection fails fast on circular dependencies (BeanCurrentlyInCreationException), forcing a redesign. Setter/field injection can resolve cycles by wiring after construction. Proxying (@Transactional) works with all styles because Spring injects the proxy, not the raw bean.

open as a page