Autowiring by Type in Spring
Type-based autowiring lets Spring inject a dependency by matching the required Java type against beans managed by the application context. It is convenient when exactly one compatible bean can satisfy the dependency.
With Spring dependency injection, a class declares what it needs and the container supplies the corresponding object. With type-based autowiring, Spring uses the dependency's type to locate a compatible bean rather than requiring the developer to specify a bean name.
For example, if a service has a constructor parameter of type `PaymentRepository` and the context contains one compatible `PaymentRepository` bean, Spring can inject it automatically. This reduces configuration and keeps the dependent class focused on its abstraction.
The important limitation is ambiguity. If multiple beans are compatible with the required type, Spring cannot normally choose between them automatically and dependency resolution fails unless additional information such as `@Qualifier` or `@Primary` identifies the intended bean.
Constructor injection is commonly preferred because dependencies are explicit and required collaborators can be represented directly in the constructor. Type matching can also be used with other injection styles, but the exact behavior depends on the injection mechanism and Spring configuration.
Key points
- Spring resolves the dependency using its compatible type.
- A single matching bean is the simplest case for successful injection.
- Multiple matching beans create ambiguity unless another selection mechanism is provided.
- `@Qualifier` can select a specific bean; `@Primary` can mark a preferred candidate.
- Constructor injection makes required dependencies explicit.
Interview questions
What does autowiring by type mean in Spring?
It means Spring resolves a dependency by looking for a bean whose type is compatible with the required dependency type. For example, a constructor requiring `UserRepository` can receive a bean implementing that interface. If there is one suitable candidate, Spring can inject it automatically. If several candidates match, additional disambiguation is normally required.
What happens if two beans have the same required type?
Spring has multiple candidates for the same dependency and cannot normally determine which one the application intends. Dependency resolution therefore fails with an ambiguity-related exception. A common solution is `@Qualifier`, which explicitly selects a bean. Another option is `@Primary`, which marks one candidate as the default.
Why is constructor injection often preferred for type-based dependency injection?
Constructor injection makes required dependencies visible in the class's constructor. It also allows the object to be created with all required collaborators already supplied. This supports immutable dependency fields and makes unit tests straightforward because dependencies can be passed directly. Type-based resolution still determines which Spring bean satisfies the constructor parameter.
How are `@Qualifier` and `@Primary` different?
`@Qualifier` explicitly narrows dependency resolution to a particular qualified candidate. `@Primary` instead marks a bean as the preferred candidate when several beans are otherwise eligible. A qualifier is useful when a particular dependency point needs a specific implementation. Primary is useful when one implementation should generally be the default.
Does autowiring by type mean Spring ignores bean names completely?
No. Type is central to the candidate-resolution process, but Spring's dependency-resolution rules can use additional metadata and fallback mechanisms. Qualifiers, primary status, and other bean-definition information can affect which candidate is selected. Therefore, it is more accurate to say that type establishes compatible candidates rather than saying names can never matter.