Key Takeaways
- Autowiring simplifies dependency injection (DI) in Spring applications.
- The
@Autowiredannotation can be applied to setters, properties, and constructors. - Ensure that components are Spring-managed beans for autowiring to work.
- Use
@Qualifierfor resolving type conflicts in autowiring.
What is Autowiring in Spring?
Autowiring makes dependency injection even easier in Spring. It leverages the framework's ability to automatically resolve and inject dependencies into your components without manually setting them up. This is a key feature of Spring's Inversion of Control (IoC) container.
Preface: Dependency Injection in Spring
Spring uses dependency injection (DI) to achieve inversion of control (IoC) within Java applications. DI decouples execution from implementation, allowing for more maintainable code.
Without DI
public class A {
private B b;
public A() {
this.b = new B();
}
}
With DI
public class A {
private B b;
public A(B b) {
this.b = b;
}
}
Notice how DI shifts control of implementation details from within the class to the external configuration.
Why We Use Autowiring in Spring
Spring registers classes as beans to manage an IoC container full of objects and dependencies. Autowiring simplifies DI by automating the injection process for these Spring-managed objects.
DI Without Autowiring
public class A {
public B b;
public void setB(B b) {
this.b = b;
}
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
A a = context.getBean(A.class);
B b = context.getBean(B.class);
a.setB(b);
a.b; // returns b
}
DI With Autowiring
@Component
public class A {
@Autowired
public B b;
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
A a = context.getBean(A.class);
a.b; // returns b
}
No need for a setter method with autowiring! As long as A and B are registered as Spring beans, B is autowired into A automatically.
Autowiring saves boilerplate code and allows Spring to handle dependency injection dynamically at runtime.
@Autowired in Spring Boot | Examples
The @Autowired annotation can be used on setters, properties, and constructors, providing flexibility in how you define dependencies.
@Autowired on Setter Methods
@Component
public class A {
private B b;
public B getB() {
return this.b;
}
@Autowired
public void setB(B b) {
this.b = b;
}
}
When @Autowired is used on a setter, the method is automatically called to inject the dependency when the bean is initialized.
When is this useful?
Use setter injection for optional dependencies or when you need to override the logic later in the implementation flow.
@Autowired on Properties
@Component
public class A {
@Autowired
private B b;
public B getB() {
return this.b;
}
}
No setter needed! Directly inject dependencies to properties for simplicity, especially when you want a concise and straightforward dependency injection approach.
@Autowired on Constructors
@Component
public class A {
private final B b;
@Autowired
public A(B b) {
this.b = b;
}
public B getB() {
return this.b;
}
}
Constructor injection is preferable for mandatory dependencies, ensuring that all required components are available upon object creation. This is also beneficial for immutable fields.
Even more magic…
Since Spring 4.3, the @Autowired annotation on constructors can often be omitted if there is only one constructor and it uses managed bean arguments. Spring manages this automatically.
@Autowired with @Qualifier
@Component("square")
public class Square implements Shape {
public int getCorners() {
return 4;
}
}
@Component("triangle")
public class Triangle implements Shape {
public int getCorners() {
return 3;
}
}
@Component
public class ShapeService {
@Autowired
@Qualifier("triangle")
private Shape shape;
}
Use @Qualifier to resolve ambiguities when multiple beans of the same type exist, allowing Spring to inject the correct one by name.
Autowire in Spring Boot Not Working?
Beans Must Be Spring-managed
Autowiring is effective only with Spring-managed beans. All examples include @Component annotations to register classes as beans. Without this registration, Spring can't manage the dependencies.
Component Scanning
The @SpringBootApplication annotation encompasses @Configuration and @ComponentScan, facilitating the automatic configuration of your application. Verify that component scanning is set up correctly to include all necessary packages.
FAQ
What's the benefit of constructor over field injection?
Constructor injection is more test-friendly and allows the definition of immutable dependencies, whereas field injection can lead to issues with uninitialized dependencies and immutability constraints.
Why use @Qualifier in Spring?
@Qualifier is crucial when you have multiple beans of the same type and need to specify which one should be injected.
What happens if no bean is found during autowiring?
If no matching bean is found, Spring will throw a NoSuchBeanDefinitionException unless the @Autowired field or parameter is marked as optional.
Can I autowire a bean from another configuration file?
Yes, as long as both configurations are scanned by Spring, you can autowire beans across different configuration files.
