Understanding @Autowired in Spring: A Comprehensive Guide
Tags: java, spring, springboot, programming
Published: 2024-06-11 01:01:32

# Introduction

The `@Autowired` annotation is one of the most common annotations when working with Spring. Its objective is simple: to tell Spring to inject a dependency bean into our beans. In other words, it will pick an instance of a bean from the Spring IoC (Inversion of Control) container and set it into our components. This will be done at the start of the Spring application when it initializes and configures all the beans.

Let’s see examples of how to work with this annotation:

## 1. Field Injection

The annotation is placed on the field. Spring will automatically locate and inject the correct bean implementation into it.

Example:

```java
javaCopy code
@Service
public class CustomerService {

    @Autowired
    private CustomerRepository customerRepository;

}

```

## 2. Setter Injection

Spring will use the set method to inject the correct bean implementation.

Example:

```java
javaCopy code
@Service
public class OrderService {

    private static final Logger log = LoggerFactory.getLogger(OrderService.class);
    private ProductCatalog productCatalog;

    @Autowired
    public void setProductCatalog(ProductCatalog productCatalog) {
        log.info("Injecting by set");
        this.productCatalog = productCatalog;
    }
}

```

## 3. Constructor Injection

You can inject the beans using the constructor. Spring will use the constructor arguments to inject the beans.

Example:

```java
javaCopy code
@Service
public class BillingService {

    private final InvoiceGenerator invoiceGenerator;

    @Autowired
    public BillingService(InvoiceGenerator invoiceGenerator) {
        this.invoiceGenerator = invoiceGenerator;
    }
}

```

Since Spring Framework 4.3, the annotation in the constructor is no longer necessary. This will work in beans with a single constructor.

Example:

```java
javaCopy code
@Service
public class ReportService {

    private ReportGenerator reportGenerator;

    public ReportService(ReportGenerator reportGenerator) {
        this.reportGenerator = reportGenerator;
    }
}

```

If your bean defines multiple constructors and has the default empty constructor, Spring will pick the default to create the bean.

Example:

```java
javaCopy code
@Service
public class NotificationService {

    private static final Logger log = LoggerFactory.getLogger(NotificationService.class);
    private EmailSender emailSender;
    private SmsSender smsSender;

    public NotificationService() {
		    log.info("Spring will pick this one");
    }

    public NotificationService(EmailSender emailSender) {
        log.info("Injecting email sender");
        this.emailSender = emailSender;
    }

    public NotificationService(EmailSender emailSender, SmsSender smsSender) {
        log.info("Injecting both");
        this.emailSender = emailSender;
        this.smsSender = smsSender;
    }
}

```

If you only have constructors with fields, you must annotate one with `@Autowired` so Spring can locate and inject the beans.

```java
javaCopy code
@Service
public class NotificationService {

    private static final Logger log = LoggerFactory.getLogger(NotificationService.class);
    private EmailSender emailSender;
    private SmsSender smsSender;

    public NotificationService(EmailSender emailSender) {
        this.emailSender = emailSender;
    }

    @Autowired
    public NotificationService(EmailSender emailSender, SmsSender smsSender) {
        log.info("Spring will inject this one");
        this.emailSender = emailSender;
        this.smsSender = smsSender;
    }
}

```

Otherwise, Spring will throw a `BeanInstantiationException`.

## 4. Marking as Not Required

By default, the fields annotated with `@Autowired` are required. If Spring does not find any instance of the correct bean to inject, it will fail to launch.

Example:

```java
javaCopy code
@Service
public class MandatoryService {

    @Autowired
    private OptionalBean mandatoryBean;

}

// Not defined as a bean
public class OptionalBean {
}

```

Spring will tell you at the start of the application:

`Field mandatoryBean in com.spring.mastery.autowired.MandatoryService required a bean of type 'com.spring.mastery.autowired.OptionalBean' that could not be found.`

But it will start if you set the property as required `false`.

Example:

```java
javaCopy code
@Service
public class MandatoryService {

    @Autowired(required = false)
    private OptionalBean mandatoryBean;

}

```

## Conclusion

Now you understand all your options when using `@Autowired` in your project!

If you like this topic, make sure to follow me. In the following days, I’ll be explaining more about Spring annotations! Stay tuned!

Follow me!

### References

- [Spring Documentation on @Autowired](https://docs.spring.io/spring-framework/reference/core/beans/annotation-config/autowired.html)
- [Baeldung on Spring Autowire](https://www.baeldung.com/spring-autowire)