Rumah  >  Artikel  >  Java  >  Apakah senario penggunaan @Configuration dalam Java?

Apakah senario penggunaan @Configuration dalam Java?

PHPz
PHPzke hadapan
2023-04-21 10:37:191802semak imbas

1. Pengenalan ringkas

@Configuration annotation boleh dianotasi pada kelas Apabila ia dianotasi pada kelas, bermula Spring akan mengimbas kelas yang dianotasi dengan @Configuration annotation dan mendaftarkannya dalam bekas IOC. . Dan dijadikan objek Bean.
Jika kelas yang diberi anotasi dengan @Configuration anotasi mengandungi kaedah untuk mencipta objek kelas tertentu yang dianotasi dengan @Bean anotasi, maka Spring juga secara automatik akan melaksanakan kaedah yang dianotasi dengan @Bean anotasi dan mendaftarkan maklumat definisi Bean yang sepadan dalam bekas IOC dan instantiated.

2. Penerangan anotasi

Anotasi @Configuration ialah anotasi jenis anotasi yang ditambahkan sejak Spring 3.0 yang membolehkan Spring menyokong pembangunan dipacu anotasi Ia digunakan terutamanya untuk anotasi pada kelas. Apabila kelas ditandakan dengan anotasi @Configuration, ini bermakna kelas ini ialah kelas konfigurasi Spring. Anotasi @Configuration boleh menggantikan fail applicationContext.xml Spring dan kelas yang ditandakan dengan anotasi @Configuration boleh didaftarkan secara automatik ke bekas IOC dan dijadikan instantiated.

1. @Kod sumber Konfigurasi

Untuk butiran kod sumber, lihat: org.springframework.context.annotation.Configuration.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
 @AliasFor(annotation = Component.class)
 String value() default "";
 // Since: 5.2
 boolean proxyBeanMethods() default true;
 // Since: 6.0
 boolean enforceUniqueMethods() default true;
}

Maksud setiap atribut dalam anotasi @Configuration adalah seperti berikut:

  • nilai: Id Bean yang disimpan dalam bekas Spring IOC.

  • proxyBeanMethods: ditambahkan pada anotasi @Configuration bermula dari Spring 5.2, menunjukkan sama ada kelas konfigurasi yang dianotasi dengan anotasi @Configuration akan diproksikan dan dijana menggunakan anotasi @Bean dalam konfigurasi kelas Sama ada objek Bean ialah objek tunggal dalam bekas IOC, nilainya adalah benar atau salah. Apabila nilai adalah benar, ia menunjukkan mod penuh (global) Dalam mod ini, kelas konfigurasi yang diberi anotasi @Configuration akan diproksikan Objek Bean yang disuntik ke dalam bekas IOC menggunakan anotasi @Bean dalam kelas konfigurasi ialah mod tunggal. Tidak kira berapa kali anda memanggil kaedah yang ditandakan dengan anotasi @Bean, objek Bean yang sama dikembalikan. Apabila nilai adalah palsu, ia menunjukkan mod ringan (ringan) Dalam mod ini, kelas konfigurasi yang dianotasi dengan anotasi @Configuration tidak akan diproksikan objek The Bean yang disuntik ke dalam bekas IOC menggunakan anotasi @Bean dalam kelas konfigurasi ialah bukan satu pun Dalam mod contoh, setiap kali kaedah yang dianotasi dengan anotasi @Bean dipanggil, objek Bean baharu akan dikembalikan. Nilai lalai adalah benar.

  • enforceUniqueMethods: Ditambahkan pada anotasi @Configuration bermula dari Spring 6.0, menyatakan sama ada kaedah yang dianotasi dengan anotasi @Bean perlu mempunyai nama kaedah yang unik, nilainya benar atau palsu. Apabila nilainya benar, ini bermakna kaedah yang dianotasi dengan anotasi @Bean mempunyai nama kaedah yang unik dan nama kaedah ini tidak bertindih. Apabila nilainya palsu, ini bermakna nama kaedah yang dianotasi dengan anotasi @Bean adalah tidak unik dan terdapat risiko bertindih. Nilai lalai adalah benar.

Ia juga boleh dilihat daripada kod sumber anotasi @Configuration bahawa anotasi @Configuration pada asasnya ialah anotasi @Component, jadi kelas konfigurasi itu sendiri diberi anotasi dengan @ Anotasi konfigurasi juga akan didaftarkan dalam bekas IOC. Pada masa yang sama, anotasi @Configuration juga akan diimbas oleh anotasi @ComponentScan.

2. Senario penggunaan @Configuration

Apabila membangunkan aplikasi berdasarkan anotasi Spring, anda boleh menganotasikan anotasi @Configuration ke kelas tertentu. Apabila kelas dianotasi dengan anotasi @Configuration, ini bermakna kelas itu ialah kelas konfigurasi Anda boleh menggunakan anotasi @Bean dalam kelas ini untuk menyuntik objek Bean ke dalam bekas IOC Anda juga boleh menggunakan @Autowired, @Inject @Resource anotasi untuk menyuntik objek Bean yang diperlukan.

Nota: Apabila membangunkan aplikasi berdasarkan mod anotasi Spring, apabila menggunakan kelas AnnotationConfigApplicationContext untuk mencipta bekas IOC, anda perlu memberi perhatian kepada perkara berikut:

(1) Jika panggilan diluluskan dalam kelas AnnotationConfigApplicationContext Pembina parameter pembolehubah jenis Kelas digunakan untuk mencipta bekas IOC, yang bermaksud objek Kelas kelas konfigurasi yang dianotasi dengan anotasi @Configuration dihantar ke dalam bekas IOC anotasi yang dianotasi pada kelas konfigurasi boleh ditinggalkan.
Jika anotasi @Configuration diabaikan pada kelas konfigurasi masuk, objek contoh Bean yang berbeza akan dikembalikan setiap kali kaedah yang dianotasi dengan anotasi @Bean dalam kelas konfigurasi dipanggil.

Kod sumber kaedah pembina yang lulus dalam parameter pembolehubah jenis Kelas dalam kelas AnnotationConfigApplicationContext adalah seperti berikut:

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    register(componentClasses);
    refresh();
}

(2) Jika panggilan untuk lulus dalam pembolehubah jenis String parameter dalam kelas AnnotationConfigApplicationContext Kaedah pembina untuk mencipta bekas IOC bermakna nama pakej aplikasi dihantar masuk untuk mencipta bekas IOC Anotasi @Configuration yang ditanda pada kelas konfigurasi tidak boleh ditinggalkan.

Kod sumber pembina yang menghantar parameter pembolehubah jenis String dalam kelas AnnotationConfigApplicationContext adalah seperti berikut:

public AnnotationConfigApplicationContext(String... basePackages) {
    this();
    scan(basePackages);
    refresh();
}

3 Kes penggunaan

1 peranan atribut proxyBeanMethods

Atribut proxyBeanMethods boleh mengambil nilai benar atau salah. Apabila nilai adalah benar, tidak kira berapa kali kaedah yang dianotasi dengan anotasi @Bean dalam kelas yang dianotasi dengan anotasi @Configuration dipanggil, objek Bean yang sama akan dikembalikan. Apabila nilainya palsu, setiap kali kaedah yang dianotasi dengan anotasi @Bean dipanggil dalam kelas yang dianotasi dengan anotasi @Configuration, objek Bean yang berbeza akan dikembalikan.

1.1 Sahkan bahawa proxyBeanMethods adalah benar

(1) Cipta kelas Orang

Kelas Orang digunakan terutamanya untuk mendaftar dalam bekas IOC dan membuat instantiat objek.

public class Person {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

(2) Cipta kelas ConfigurationAnnotationConfig

ConfigurationAnnotationConfig类的作用就是充当程序启动的配置类,会在ConfigurationAnnotationConfig类上标注@Configuration注解,说明ConfigurationAnnotationConfig类是Spring启动时的配置类。

@Configuration
public class ConfigurationAnnotationConfig {
    @Bean
    public Person person(){
        return new Person();
    }
}

可以看到,在ConfigurationAnnotationConfig类上标注了@Configuration注解,由于@Configuration注解中的proxyBeanMethods属性默认为true,所以在ConfigurationAnnotationConfig类上的@Configuration注解省略了proxyBeanMethods属性。

(3)创建ConfigurationAnnotationTest类

ConfigurationAnnotationTest类的作用就是整个案例程序的启动类,对整个案例程序进行测试。

public class ConfigurationAnnotationTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationAnnotationTest.class);

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigurationAnnotationConfig.class);
        ConfigurationAnnotationConfig config = context.getBean(ConfigurationAnnotationConfig.class);
        Person person1 = config.person();
        Person person2 = config.person();
        LOGGER.info("person1 == person2 ===>> {}", (person1 == person2));
    }
}

可以看到,在ConfigurationAnnotationTest类的main()方法中,首先基于AnnotationConfigApplicationContext常见了IOC容器context,从context中获取了ConfigurationAnnotationConfig类的Bean实例对象config,接下来,调用两次config的person()方法分别赋值给Person类型的局部变量person1和person2,最后打印person1是否等于person2的日志。

(4)测试案例

运行ConfigurationAnnotationTest类的main()方法,输出的结果信息如下所示。

person1 是否等于 person2 ===>> true

通过输出的结果信息可以看出,person1是否等于person2输出的结果为true。说明当@Configuration注解中的proxyBeanMethods属性为true时,每次调用使用@Configuration注解标注的类中被@Bean注解标注的方法时,都会返回同一个Bean实例对象。

1.2 验证proxyBeanMethods取值为false的情况

验证@Configuration注解中的proxyBeanMethods属性为false的情况,与验证proxyBeanMethods属性为true的情况的案例程序基本一致,只是将ConfigurationAnnotationConfig类上标注的@Configuration注解的proxyBeanMethods属性设置为false,案例实现的具体步骤如下所示。

(1)修改proxyBeanMethods属性的值

@Configuration(proxyBeanMethods = false)
public class ConfigurationAnnotationConfig {
    @Bean
    public Person person(){
        return new Person();
    }
}

(2)测试案例
运行ConfigurationAnnotationTest类的main()方法,输出的结果信息如下所示。

person1 是否等于 person2 ===>> false

从输出的结果信息可以看出,person1是否等于person2输出的结果为false。说明当@Configuration注解中的proxyBeanMethods属性为false时,每次调用使用@Configuration注解标注的类中被@Bean注解标注的方法时,都会返回不同的Bean实例对象。

2. 传入配置类创建IOC容器

调用AnnotationConfigApplicationContext类的构造方法传入配置类的Class对象创建IOC容器时,可以省略配置类上的@Configuration注解,案例的具体实现步骤如下所示。

(1)删除@Configuration注解

public class ConfigurationAnnotationConfig {
    @Bean
    public Person person(){
        return new Person();
    }
}

(2)测试案例
运行ConfigurationAnnotationTest类的main()方法,输出的结果信息如下所示。

person1 是否等于 person2 ===>> false

从输出的结果信息可以看到,输出了person1是否等于person2的结果为false。说明调用AnnotationConfigApplicationContext类的构造方法传入配置类的Class对象创建IOC容器时,可以省略配置类上的@Configuration注解,此时每次调用配置类中被@Bean注解标注的方法时,都会返回不同的Bean实例对象。

3. 传入包名创建IOC容器

调用AnnotationConfigApplicationContext类的构造方法传入包名创建IOC容器时,不能省略配置类上的@Configuration注解,案例的具体实现步骤如下所示。

(1)修改测试类

修改ConfigurationAnnotationTest类的main()方法中,创建AnnotationConfigApplicationContext对象的代码,将调用传入Class对象的构造方法修改为调用传入String对象的方法,修改后的代码如下所示。

public class ConfigurationAnnotationTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationAnnotationTest.class);

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.lwk.demo.spring.annocation.configuration.config");
        ConfigurationAnnotationConfig config = context.getBean(ConfigurationAnnotationConfig.class);
        Person person1 = config.person();
        Person person2 = config.person();
        LOGGER.info("person1 是否等于 person2 ===>> {}", (person1 == person2));
    }
}

(2)删除@Configuration注解

public class ConfigurationAnnotationConfig {
    @Bean
    public Person person(){
        return new Person();
    }
}

(3)测试案例

运行ConfigurationAnnotationTest类的main()方法,可以看到程序抛出了异常信息,如下所示。

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.binghe.spring.annotation.chapter01.configuration.config.ConfigurationAnnotationConfig' available

从输出的结果信息可以看出,调用AnnotationConfigApplicationContext类的构造方法传入包名创建IOC容器时,不能省略配置类上的@Configuration注解,否则会抛出NoSuchBeanDefinitionException。

(4)添加@Configuration注解

@Configuration
public class ConfigurationAnnotationConfig {
    @Bean
    public Person person(){
        return new Person();
    }
}

(5)再次测试案例

再次运行ConfigurationAnnotationTest类的main()方法,输出的结果信息如下所示。

person1 是否等于 person2 ===>> true

Daripada maklumat hasil output, kita dapat melihat bahawa hasil output sama ada person1 sama dengan person2 adalah benar Sekali lagi, apabila memanggil kaedah pembina kelas AnnotationConfigApplicationContext dan menghantar nama pakej untuk mencipta IOC. bekas, @ pada kelas konfigurasi tidak boleh ditinggalkan.

Atas ialah kandungan terperinci Apakah senario penggunaan @Configuration dalam Java?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam