1. @Component
@Component được áp dụng cho Class, khi Class được gán @Component
cho chúng ta biết bean được tạo ra và quản lý bởi Spring Boot.
2. @Autowired
@Autowired được áp dụng cho setter, constructor, instance variable. Khi chúng ta gán @Autowired
Spring container sẽ tự động tạo ra liên kết tương ứng vơi data-type.
3. Ví dụ thực tế và Giải thích
Để hiểu rõ hai khái niệm trên chúng ta xây dựng một application có sử dụng dịch vụ S3 của AWS như sau:-
- Thiết lập cấu hình kết nối với AWS bằng
@Configuration
và khởi tạo@Bean
amazonS3.@Configuration public class AmazonS3Config { @Value("${amazon.s3.region}") String region; @Value("${amazon.s3.accessKey}") String accessKey; @Value("${amazon.s3.secretKey}") String secretKey; @Bean public AmazonS3 amazonS3() { return AmazonS3ClientBuilder .standard() .withCredentials(new AWSStaticCredentialsProvider(credentials())) .withRegion(Regions.fromName(region)) .build(); } public AWSCredentials credentials() { return new BasicAWSCredentials(accessKey, secretKey); } }
- Định nghĩa bean S3Client bằng annotation
@Component
và inject bean amazonS3 vào trong S3Client.@Component @Slf4j(topic = "S3-SERVICE") public class S3Client { @Autowired private AmazonS3 amazonS3Client; public void createS3Bucket(String bucketName, boolean publicBucket) { if (amazonS3Client.doesBucketExistV2(bucketName)) { log.info("Bucket name already in use. Try another name."); return; } if (publicBucket) { amazonS3Client.createBucket(bucketName); } else { amazonS3Client.createBucket(new CreateBucketRequest(bucketName).withCannedAcl(CannedAccessControlList.Private)); } } public List listBuckets() { return amazonS3Client.listBuckets(); } }
- Cuối cùng chúng ta tạo một RestController và inject s3Client vào để gọi các method phía trên.
@RestController @RequestMapping("/s3") public class S3Controller { @Autowired private S3Client s3Client; @PostMapping(value = "/{bucketName}") public void createBucket(@PathVariable String bucketName, @RequestParam boolean publicBucket) { s3Client.createS3Bucket(bucketName, publicBucket); } @GetMapping(path = "/buckets") public List listBuckets() { var buckets = s3Client.listBuckets(); return buckets.stream().map(Bucket::getName).toList(); } }
- Kết luận: Qua ví dụ các bạn có thể thấy rằng annotation
@Component
đơn giản là để khai báo cho Spring Container biết đây là một bean cần Spring Container khởi tạo và quản lý trong application context.@Autowired
là annotation cho phép bạn inject một bean này vào một bean khác dựa trên nguyên tắc Dependency Injection. (Dependency Injection là một nguyên tắc trong lập trình nhắm làm giảm sự phụ thuộc giữa cách thành phần trong ứng dụng với nhau) - Chú ý: Đây là một bài phân tích sự khác nhau giữa 2 annotation, trong các ứng dụng thực tế các developer không ưa thích cách inject này bởi nó tự động tạo ra mối liên kết mơ hồ trong nhiều tình huống nó đem lại một số bug do tạo ra liên kết sai khi chúng ta áp dụng các mô hình đa kế thừa. Các bạn đọc thêm ở đây để biết thêm nhé Limitations and Disadvantages of Autowiring