Trong bài viết này, chúng ta sẽ thảo luận về "Spring Boot Bean Annotations qua các ví dụ". Không cần phải nói, những Anotations này đóng một vai trò quan trọng trong việc tạo các ứng dụng Spring boot cơ bản cũng như cấp doanh nghiệp. Nếu bạn muốn tìm hiểu tất cả các Anotations thường được sử dụng trong Spring Boot Project, vui lòng truy cập bài viết Spring Boot Annotations with Examples'. 

Annotations on Bean Properties

Hãy bắt đầu thảo luận về Annotations on Bean Properties Bean từ bài viết ‘Spring Boot Bean Annotations qua các ví dụ’.

@Lazy 

Theo mặc định, Spring tạo tất cả các singleton bean  khi khởi động cấu trúc của application context. Tuy nhiên, trong một số trường hợp khi chúng ta cần tạo bean, không phải lúc khởi động application context mà là khi chúng ta yêu cầu. Trong trường hợp đó, chúng tôi áp dụng @Lazy . Khi chúng tôi đặt chú thích @Lazy trên lớp @Configuration , nó chỉ ra rằng tất cả các phương thức có chú thích @Bean chỉ được khởi tạo khi có lời gọi đến chứ không khởi tạo ngay khi ứng dụng Spring Boot khởi động . Hơn nữa, điều này là tương đương với thuộc tính default-lazy-init = "true" của cấu hình dựa trên XML . Bean không được chú thích bằng @Lazy được khởi tạo. Ví dụ: mã bên dưới minh họa việc sử dụng chú thích @Lazy :

@Configuration
public class AppConfig {
     @Lazy
     @Bean
     public Employee getEmployee() {
          return new Employee();
     }
}

Dùng @Lazy cùng với  chú thích @Bean để làm chậm, trễ lại quá trình khởi tạo Bean component.

@Profile

Trước khi đi vào @Profile , hãy hiểu khái niệm về Profile trong Spring Boot. Spring Profiles cung cấp một cách để chia nhỏ các phần của cấu hình ứng dụng của bạn và làm cho nó chỉ khả dụng trong một số môi trường nhất định. Tất cả chúng ta đều biết rằng chúng ta có nhiều môi trường khác nhau để phát triển một dự án như Development, Test, UAT, Production... Thực tế, chúng ta có các cấu hình cụ thể cho một môi trường cụ thể như tên máy chủ, cổng, v.v. Hơn nữa, một số bean cụ thể cần được khởi tạo tại một địa chỉ cụ thể Môi trường. Bây giờ chúng ta hãy quan sát cách chúng ta có thể làm cho một Bean thuộc một Profile cụ thể.

Chúng tôi sử dụng chú thích @Profile chỉ ra rằng chúng tôi đang ánh xạ bean tới cấu hình cụ thể đó. Nó chỉ ra rằng bean sẽ chỉ được khởi tạo nếu các cấu hình được xác định đang hoạt động. Anotations chỉ lấy tên của một hoặc nhiều cấu hình. Ví dụ, chúng ta hãy xem xét chúng ta có một bean chỉ nên hoạt động trong quá trình development không được triển khai lên Product. Chúng tôi chú thích bean đó bằng một development profile và nó sẽ chỉ hiện diện trong vùng chứa trong quá trình development. Nhưng trong Production, development sẽ không hoạt động.

@Component
@Profile("development")
public class MyConfigClass{ }

@Scope 

Phạm vi của bean cho biết vòng đời và khả năng hiển thị của bean đó trong các ngữ cảnh mà nó được sử dụng. Spring framework xác định 6 loại phạm vi theo phiên bản mới nhất.

singleton
prototype
request
session
application
websocket

Trong số sáu phạm vi nói trên, bốn phạm vi chỉ khả dụng nếu chúng ta sử dụng web-aware ApplicationContext. Tuy nhiên, phạm vi Singleton và nguyên mẫu có sẵn trong bất kỳ loại thùng chứa IOC nào. Để khai báo phạm vi của bean, chúng ta sử dụng chú thích @Scope. Nếu không có phạm vi nào được chỉ định, phạm vi Singleton là giá trị mặc định. Ví dụ, để khai báo phạm vi nguyên mẫu, chúng ta sẽ sử dụng @Scope như sau:

@Scope("prototype")
@Bean
public Student studentPrototype() {
     return new Student();
}

@DependsOn

Khi một bean phụ thuộc vào bean khác, chúng tôi sử dụng chú thích @DependsOn. Ngoài ra, nếu bạn cần khởi tạo bất kỳ bean nào trước một bean khác, @DependsOn sẽ giúp bạn thực hiện công việc này. Trong khi tạo bean, chúng ta cần xác định giá trị của thuộc tính @DependsOn như một bean phụ thuộc. Hơn nữa, thuộc tính @DependsOn có thể buộc một hoặc nhiều bean được khởi tạo một cách rõ ràng trước khi bean hiện tại được khởi tạo. Ví dụ, giả sử rằng chúng ta có hai bean BeanA và BeanB và BeanB phụ thuộc vào BeanA. Do đó, mã của chúng tôi sẽ giống như dưới đây:

@Component
public class BeanA { }

@Component
public class BeanB { }

@Component
@DependsOn(value = {"beanA","beanB"})
public class BeanC { }

@Order

Các @Order chú thích xác định thứ tự sắp xếp của một thành phần Anotations hoặc một bean. Nó có một đối số 'giá trị' tùy chọn xác định thứ tự thực thi của thành phần. Tuy nhiên, giá trị mặc định là Có thứ tự.LOWEST_PRECEDENCE. Tương tự Order.HIGHEST_PRECEDENCE chỉ ra rằng thành phần có mức độ ưu tiên cao nhất trong số các thành phần. Nếu chúng tôi cung cấp giá trị order trong thuộc tính @Order, thì số thấp hơn có mức độ ưu tiên cao nhất, tức là. chú thích thứ tự với 1 sẽ chạy trước 2. Chúng tôi thậm chí có thể cung cấp số âm. Thứ tự có giá trị nhỏ hơn sẽ luôn được ưu tiên. Nếu Thành phần / Bean không có @Order, theo mặc định, nó sẽ thực thi theo thứ tự bảng chữ cái của tên bean. Hơn nữa nếu hai thành phần có cùng giá trị thứ tự, thứ tự bảng chữ cái của tên thành phần sẽ thắng.

♥ Lưu ý: Thứ tự thực hiện sẽ như sau:
Các thành phần đầu tiên có giá trị thứ tự là số âm
Sau đó các thành phần có giá trị thứ tự là số dương
Sau đó không có thành phần giá trị thứ tự theo thứ tự bảng chữ cái tên của chúng

Ví dụ, hãy quan sát đoạn mã dưới đây:

@Component
@Order(-1)
public class A { }

@Component
@Order(5)
public class D { }

@Component
@Order(-24)
public class C { }

@Component
@Order(5)
public class B { }

@Component
public class F { }

@Component

Từ các thành phần trên, thứ tự thực hiện sẽ là: C, A, B, D, E, F

@Primary 

Khi chúng ta có nhiều bean cùng loại, chúng ta sử dụng @Primary để ưu tiên cao hơn cho một loại bean cụ thể. Ví dụ, giả sử rằng chúng ta có hai loại bean PermanentE Employee và ContractE Employee thuộc loại Employee. Ở đây, chúng tôi muốn ưu tiên cho PermanentEFastee. Hãy quan sát đoạn mã dưới đây để biết cách chúng ta sẽ áp dụng @Primary để tạo ưu tiên.

@Component
public class ContractEmployee implements Employee { }

@Component  
@Primary
public class PermanentEmployee implements Employee { }

@Service
public class EmployeeService {
    @Autowired
    private Employee employee;
    public Employee getEmployee() {
         return employee;
    }
}

Không cần phải nói, trong lớp EmployeeService ở trên, PermanentEFastee sẽ được đưa vào thông qua autowiring.

♥ Lưu ý: Nếu chúng tôi không cung cấp @Primary trong thành phần PermanentErantyee và cố gắng chạy ứng dụng, Spring sẽ ném NoUniqueBeanDefinitionException. Tuy nhiên, để truy cập các bean cùng loại, chúng tôi thường sử dụng chú thích @Qualifier ("beanName") . Trên thực tế, chúng tôi áp dụng nó tại điểm tiêm cùng với @Autowired. Trong trường hợp của chúng tôi, vì chúng tôi đã chọn các bean ở giai đoạn cấu hình nên chúng tôi không thể áp dụng chú thích @Qualifier ở đây.

@Conditional

Nếu một @Configuration lớp được đánh dấu bằng @Conditional, tất cả các @Bean methods@import anotations, và @ComponentScan annotations  liên quan đến lớp đó sẽ phải chịu các điều kiện. Tóm lại, bannotated bean chỉ được tạo ra nếu tất cả các điều kiện được thỏa mãn. Spring 4.0 đã giới thiệu annotation @Conditional mới này cho phép chúng tôi sử dụng các điều kiện tùy chỉnh hoặc được xác định trước mà chúng tôi có thể áp dụng cho bean trong application context. Ví dụ: hãy xem một condition được xác định trước với @ConditionalOnJava . 

@Bean
@ConditionalOnJava(value = JavaVersion.NINE)
public JavaBean getJavaBean(){
    return new JavaBean();
}

Bây giờ chúng ta hãy xem chú thích có điều kiện được xác định trước phổ biến nhất và được sử dụng phổ biến nhất là @ConditionalOnProperty trong các dự án Spring Boot. Nó cho phép tải beans conditionally tùy thuộc vào một thuộc tính môi trường nhất định:

@Configuration
@ConditionalOnProperty(
        value="module.enabled", 
        havingValue = "true", 
        matchIfMissing = true
        )
class MyPaymentModule {
...
}

MyPaymentModule chỉ được tải nếu thuộc tính module.enabled có giá trị true. Nếu thuộc tính không được đặt ở tất cả, nó sẽ vẫn được tải, vì chúng tôi đã xác định matchIfMissing là true. Bằng cách này, chúng tôi đã tạo một mô-đun được tải theo mặc định cho đến khi chúng tôi quyết định khác.

  • @ConditionalOnProperty
  • @ConditionalOnExpression
  • @ConditionalOnBean
  • @ConditionalOnMissingBean
  • @ConditionalOnResource

Các conditional annotations được mô tả ở trên là những anotations phổ biến hơn mà chúng tôi có thể sử dụng trong bất kỳ ứng dụng Spring Boot nào. Spring Boot cung cấp nhiềuconditional annotations  hơn. Tuy nhiên, chúng không phổ biến bằng và một số chúng thích hợp hơn để phát triển ramework development là phát triển ứng dụng. Mặc dù Spring Boot framework sử dụng một số trong số chúng một cách chuyên sâu.

  • @ConditionalOnClass
  • @ConditionalOnMissingClass
  • @ConditionalOnJndi
  • @ConditionalOnJava
  • @ConditionalOnSingleCandidate
  • @ConditionalOnWebApplication
  • @ConditionalOnNotWebApplication
  • @ConditionalOnCloudPlatform

Tham khảo tại đây