Blog

The 5 Minute Guide to Autowire in Spring

Key Takeaways

  • Autowiring simplifies dependency injection (DI) in Spring applications.
  • The @Autowired annotation can be applied to setters, properties, and constructors.
  • Ensure that components are Spring-managed beans for autowiring to work.
  • Use @Qualifier for 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.

Mastering the tech interviewWhat everyone is doing wrong in tech interviews