post-image

Hướng dẫn sử dụng @Autowired trong Spring (phần 2)

Spring Data JPA

Tại bài viết trước chúng ta đã tìm hiểu qua @Autowired qua 1 số trường hợp, trong bài viết này chúng ta sẽ tìm hiểu thêm 1 số trường hợp khác nữa nhé.

4. @Autowired và Optional Dependencies

Khi một bean đang được xây dựng, các phụ thuộc @Autow mong muốn sẽ có sẵn. Ngược lại, nếu Spring không thể giải quyết một bean để nối dây, nó sẽ ném ra một ngoại lệ.

Do đó, nó ngăn không cho vùng chứa Spring khởi chạy thành công với một ngoại lệ của biểu mẫu:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.autowire.sample.FooDAO] found for dependency: 
expected at least 1 bean which qualifies as autowire candidate for this dependency. 
Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true)}Code language: JavaScript (javascript)

Để khắc phục điều này, chúng ta cần khai báo một bean thuộc kiểu bắt buộc:

public class FooService {
    @Autowired(required = false)
    private FooDAO dataAccessor; 
}Code language: PHP (php)

5. Autowire Disambiguation

heo mặc định, Spring giải quyết các mục nhập @Autowire mong muốn theo loại. Nếu có nhiều hơn một bean cùng loại trong vùng chứa, thì khung công tác sẽ đưa ra một ngoại lệ nghiêm trọng.

Để giải quyết xung đột này, chúng ta cần nói rõ ràng với Spring mà chúng ta muốn đưa vào bean nào.

5.1. Autowiring by @Qualifier

Ví dụ, hãy xem cách chúng ta có thể sử dụng chú thích @Qualifier để chỉ ra bean được yêu cầu.

Đầu tiên, chúng ta sẽ xác định 2 bean kiểu Formatter:

@Component("fooFormatter")
public class FooFormatter implements Formatter {
    public String format() {
        return "foo";
    }
}
Code language: PHP (php)
@Component("barFormatter")
public class BarFormatter implements Formatter {
    public String format() {
        return "bar";
    }
}Code language: PHP (php)

Bây giờ chúng ta hãy thử đưa một bean Formatter vào lớp FooService:

public class FooService {
    @Autowired
    private Formatter formatter;
}Code language: PHP (php)


Trong ví dụ của chúng tôi, có hai triển khai cụ thể của Formatter có sẵn cho vùng chứa Spring. Do đó, Spring sẽ ném ra một ngoại lệ NoUniqueBeanDefinitionException khi xây dựng FooService:

THAM KHẢO WEBSITE SPRING BOOT

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type [com.autowire.sample.Formatter] is defined: 
expected single matching bean but found 2: barFormatter,fooFormatterCode language: CSS (css)

Chúng tôi có thể tránh điều này bằng cách thu hẹp việc triển khai bằng cách sử dụng chú thích @Qualifier:

public class FooService {
    @Autowired
    @Qualifier("fooFormatter")
    private Formatter formatter;
}Code language: PHP (php)

Khi có nhiều bean cùng loại, bạn nên sử dụng @Qualifier để tránh sự mơ hồ.

Xin lưu ý rằng giá trị của chú thích @Qualifier khớp với tên được khai báo trong chú thích @Component của quá trình triển khai FooFormatter của chúng tôi.

5.2. Autowiring by Custom Qualifier

Spring cũng cho phép chúng tôi tạo chú thích @Qualifier tùy chỉnh của riêng mình. Để làm như vậy, chúng tôi nên cung cấp chú thích @Qualifier với định nghĩa:

@Qualifier
@Target({
  ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface FormatterType {  
    String value();
}Code language: CSS (css)

Sau đó, chúng ta có thể sử dụng FormatterType trong các triển khai khác nhau để chỉ định một giá trị tùy chỉnh:

@FormatterType("Foo")
@Component
public class FooFormatter implements Formatter {
    public String format() {
        return "foo";
    }
}Code language: PHP (php)
@FormatterType("Bar")
@Component
public class BarFormatter implements Formatter {
    public String format() {
        return "bar";
    }
}Code language: PHP (php)

Cuối cùng, chú thích Bộ định mức tùy chỉnh đã sẵn sàng để sử dụng cho tự động chia sẻ:

5.3. Autowiring by Name

Spring sử dụng tên bean làm giá trị định tính mặc định. Nó sẽ kiểm tra vùng chứa và tìm một bean có tên chính xác như thuộc tính để tự động truyền tải nó.

Do đó, trong ví dụ của chúng tôi, Spring đối sánh tên thuộc tính fooFormatter với việc triển khai FooFormatter. Do đó, nó sẽ chèn triển khai cụ thể đó khi xây dựng FooService:

public class FooService {
 @Autowired 
private Formatter fooFormatter; 
}Code language: PHP (php)

6. Kết luận

Trong bài viết này, chúng ta đã thảo luận về tính năng tự động tạo và các cách khác nhau để sử dụng nó. Chúng ta cũng đã kiểm tra các cách để giải quyết hai trường hợp ngoại lệ autowiring phổ biến gây ra bởi một hạt đậu bị thiếu hoặc một hạt đậu không rõ ràng.

Happy learning!!!

Các lựa chọn khác khi không muốn dùng GitHub

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *