Spring - Cấu hình dựa trên Java: Sử dụng @Configuration
Bài viết gốc xem tại : https://www.logicbig.com/tutorials/spring-framework/spring-core/java-config.html

Ví dụ khởi động Spring kick của chúng tôi đã trình bày ngắn gọn phương pháp cấu hình JavaConfig. Sau đây chúng ta sẽ tìm hiểu chi tiết.

@Configuration

Đây là một chú thích cấp độ lớp. Lớp được chú thích bằng chú thích này có thể bao gồm các phương thức được chú thích bằng @Bean. Spring container gọi các phương thức như vậy để lấy các thể hiện đối tượng, để container có thể đăng ký chúng dưới dạng bean.
 

package spring.example

@Configuration
public class MyAppConfig {
  @Bean
  public SomeBean someBean() {
  // instantiate, configure and return bean instance ...
  return new SomeBeanImpl();
  }
}

Cấu hình XML tương đương sẽ giống như sau:

<bean name="someBean" class="spring.example.SomeBeanImpl"/>

Các lớp @Configuration thực chất không có gì khác ngoài các nhà máy được quản lý bằng factories để tạo và đăng ký các cá thể bean.

Bootstrapping Spring Container

Trong cấu hình  spring configuration dựa trên Java, container có thể được bootstrapped sử dụng một trong hai AnnotationConfigApplicationContexthoặc cho các ứng dụng web: AnnotationConfigWebApplicationContext.

new AnnotationConfigApplicationContext(MyAppConfig.class);

Chúng tôi cũng có thể chỉ định tên gói đủ điều kiện có chứa các lớp được chú thích @Configuration:

new AnnotationConfigApplicationContext("spring.example");

Bằng cách sử dụng biến thể quá tải ở trên, chúng ta có thể có nhiều lớp cấu hình trong một gói duy nhất

@Configuration Class được CGLIB phân loi

  • Tất cả các lớp @Configuration đều được phân lớp tại thời điểm khởi động với CGLIB. Trong lớp con, phương thức con sẽ kiểm tra vùng chứa trước để xem có bất kỳ bean nào được lưu trong bộ nhớ cache (phạm vi) trước khi nó gọi phương thức cha và tạo một thể hiện mới.
  • CGLIB ủy quyền là phương tiện mà theo đó gọi các phương thức hoặc trường bên trong phương thức @Bean trong các lớp @Configuration tạo ra các tham chiếu siêu dữ liệu bean đến các đối tượng cộng tác; các phương thức như vậy không được gọi với ngữ nghĩa Java thông thường mà đi qua vùng chứa để cung cấp quản lý vòng đời thông thường và ủy quyền của Spring bean ngay cả khi tham chiếu đến các bean khác thông qua các lệnh gọi có lập trình tới phương thức @Bean.

Đó là lý do tại sao tất cả các phương thức sẽ trả về cùng một thể hiện ở nhiều lần gọi (nếu chúng là phạm vi singleton, là phạm vi mặc định).

Cần phải có @Configurationchú thích, nếu không thì thao tác thời gian chạy này sẽ không được thực hiện.

 

@ComponentScan

Cho đến nay, chúng ta đã thấy JavaConfig sử dụng các phương thức gốc (chú thích bằng @Bean) để cung cấp việc triển khai bean. Sử dụng cách tiếp cận này, chúng ta phải tự tạo các phiên bản thực thi bean. Thay vì cách tiếp cận nhà máy này, chúng tôi có thể có mùa xuân để quét các gói được cung cấp và tạo tất cả việc triển khai tự động và sau đó đưa các phần phụ thuộc vào. Chúng tôi có thể làm điều đó bằng cách sử dụng @ComponentScancùng với @Configuration. Chúng tôi vẫn không phải sử dụng bất kỳ XML nào. Vui lòng xem một ví dụ tại đây

Ví dụ Sử dụng chú thích @Configuration
 

package com.logicbig.example;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ConfigExample {
    private int counter;

    @Bean
    public Greeter greeterBean() {
        return new Greeter();
    }

    public static void main(String... strings) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(ConfigExample.class);
        Greeter greeter = context.getBean(Greeter.class);
        greeter.sayHi("Joe");
    }

    public static class Greeter {
        public void sayHi(String name) {
            System.out.println("Hi there, " + name);
        }

    }
}

Output

Hi there, Joe

 

Demo cho thao tác CGLIB ca các lp @Configuration

Các lớp @Configuration được CGLIB phân lớp, xử lý các phương thức @Bean để kiểm soát vòng đời của chúng. Các cá thể bean được tạo bởi các phương thức proxy này được lưu vào bộ nhớ đệm. Đó là lý do tại sao tất cả các phương thức bean sẽ trả về cùng một thể hiện nếu được gọi nhiều lần.

package com.logicbig.example;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DemoCGLIB {
  private int counter;

  @Bean
  public String something(){
      System.out.println("method invoked");
      return String.valueOf(++counter);
  }

      public static void main(String... strings) {
          AnnotationConfigApplicationContext context =
                  new AnnotationConfigApplicationContext(DemoCGLIB.class);
          DemoCGLIB bean = context.getBean(DemoCGLIB.class);
          System.out.println(bean.something());
          System.out.println(bean.something());
      }
}

Output

method invoked
1
1

Hãy xóa chú thích @Bean khỏi phương thức something () và xem sự khác biệt:

package com.logicbig.example;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WithoutCGLIB {
  private int counter;

  public String something(){
      System.out.println("method invoked");
      return String.valueOf(++counter);
  }

      public static void main(String... strings) {
          AnnotationConfigApplicationContext context =
                  new AnnotationConfigApplicationContext(WithoutCGLIB.class);
          WithoutCGLIB bean = context.getBean(WithoutCGLIB.class);
          System.out.println(bean.something());
          System.out.println(bean.something());
      }
}

Output

method invoked
1
method invoked
2