Dependency Injection in Spring using different annotations

Dependency Injection in Spring using different annotations

In this article, we will discuss some of the annotations which we can use to create, use or configure beans in the Spring framework.

In the Spring Framework, beans are the fundamental building blocks used for dependency injection and inversion of control. You can work with beans in Spring using various annotations. Here are some commonly used annotations and their purposes:

@Component

This annotation is used to mark a class as a Spring component. Spring will automatically detect and instantiate the beans marked with this annotation. For example:

import org.springframework.stereotype.Component;

@Component
public class FileService {
    // ...
}

@Autowired

This annotation is used to automatically wire beans together by letting Spring resolve and inject the dependencies. It can be used on fields, constructors, or methods. For example:

import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;

@Component
public class ProductService {
    private ProductDB db;
    private SecondService secondService;

    // Constructor injection
    @Autowired
    public ProductService(ProductDB db) {
        this.db = db;
    }

    // Method injection
    @Autowired
    public void setSecondService(SecondService s) {
        this.secondService = s;
    }

    // Field injection
    @Autowired
    private final ThirdService s3;
}

@Qualifier

When there are multiple beans of the same type, this annotation is used along with @Autowired to specify which bean should be injected. You can provide a unique name or identifier to differentiate between the beans. For example:

import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Qualifier;

@Component
@Qualifier("gcpfs")
public class GCPFileService implements FileService {
    // ...
}

@Component
@Qualifier("awsfs")
public class AWSFileService implements FileService {
    // ...
}

@Component
public class ProductService {
    @Autowired
    @Qualifier("gcpfs")
    private FileService fileService;

    // ...
}

@Value

This annotation injects values from properties files or environment variables into beans. It can be applied to fields, constructors, or methods. For example:

import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Value;

@Component
public class StorageService {
    @Value("${storage.url}")
    private String storageUrl;

    // ...
}

@Configuration

This annotation is used to define a configuration class that provides bean definitions. It is often used in conjunction with @Bean annotations. For example:

import org.springframework.context.annotation.Configuration;

@Configuration
public class DbConfig {
    @Bean
    public Connection dbConnection() {
        return Driver.getConnection(....);
    }

    // ...
}

In addition to the annotations I mentioned earlier, Spring provides specific annotations for certain types of beans. Two commonly used annotations are @Service and @Repository.

@Service

This annotation indicates that a class represents a service in the application's business layer. It typically encapsulates the business logic and performs operations on data received from the presentation layer. For example:

import org.springframework.stereotype.Service;

@Service
public class ProductService {

    public void addProduct(Product product) {
        // ...
    }

    // ...
}

@Repository

This annotation indicates that a class represents a repository or a data access object (DAO) in the persistence layer. It typically handles the storage and retrieval of data from the database or any other data source. For example:

import org.springframework.stereotype.Repository;

@Repository
public interface ProductRepository extends JpaRepository<Product, Integer> {
    // Methods for database operations
}

These annotations provide additional semantic meaning to the beans in your application, making it easier to understand their purpose and role within the overall architecture. By using @Service and @Repository, you can better organize and categorize your beans based on their responsibilities. Note that both @Service and @Repository are specializations of the @Component annotation. This means they functionally work the same way as @Component but provide more specific context and intention in your codebase. They can be used interchangeably with @Component, but using the appropriate annotation enhances code readability and maintainability.

Conclusion

These are just a few examples of annotations used in Spring Framework to work with beans. Spring provides many more annotations for different scenarios and use cases. It's important to understand the purpose and usage of each annotation to effectively work with beans in Spring. That's it for now. Thanks for your time. Please give suggestions, like and subscribe to my newsletter. Will meet in the next one.