Maison  >  Article  >  Java  >  Quels sont les scénarios d’utilisation de @Configuration en Java ?

Quels sont les scénarios d’utilisation de @Configuration en Java ?

PHPz
PHPzavant
2023-04-21 10:37:191802parcourir

1. Brève introduction

L'annotation @Configuration peut être annotée sur une classe, le démarrage de Spring analysera automatiquement la classe annotée avec l'annotation @Configuration, l'enregistrera dans le conteneur IOC et l'instanciera dans un fichier. Objet haricot.
Si la classe annotée avec l'annotation @Configuration contient une méthode pour créer un certain objet de classe annoté avec l'annotation @Bean, alors Spring exécutera également automatiquement la méthode annotée avec l'annotation @Bean et enregistrera les informations de définition du Bean correspondantes dans le conteneur IOC. et instanciez-le.

2. Description de l'annotation

@L'annotation de configuration est une annotation de type annotation ajoutée depuis Spring 3.0 qui permet à Spring de prendre en charge le développement basé sur les annotations. Elle est principalement utilisée pour l'annotation sur les classes. Lorsqu'une classe est marquée de l'annotation @Configuration, cela signifie que cette classe est une classe de configuration Spring. L'annotation @Configuration peut remplacer le fichier applicationContext.xml de Spring, et les classes marquées avec l'annotation @Configuration peuvent être automatiquement enregistrées dans le conteneur IOC et instanciées.

1. Code source de @Configuration

Pour plus de détails sur le code source, veuillez consulter : 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;
}

La signification de chaque attribut dans l'annotation @Configuration est la suivante :

  • value : L'identifiant du Bean stocké dans le conteneur Spring IOC.

  • proxyBeanMethods : ajouté à l'annotation @Configuration à partir de Spring 5.2, indiquant si la classe de configuration annotée avec l'annotation @Configuration sera proxy et si l'objet Bean généré à l'aide de l'annotation @Bean dans la classe de configuration est dans le Objet Singleton du conteneur IOC, la valeur est vraie ou fausse. Lorsque la valeur est vraie, elle indique le mode complet (global). Dans ce mode, la classe de configuration annotée avec l'annotation @Configuration sera proxy. L'objet Bean injecté dans le conteneur IOC à l'aide de l'annotation @Bean dans la classe de configuration est en mode singleton. Quel que soit le nombre de fois que vous appelez une méthode marquée de l'annotation @Bean, le même objet Bean est renvoyé. Lorsque la valeur est fausse, cela indique un mode léger (léger). Dans ce mode, la classe de configuration annotée avec l'annotation @Configuration ne sera pas proxy. L'objet Bean injecté dans le conteneur IOC à l'aide de l'annotation @Bean dans la classe de configuration est. pas un seul Dans le mode exemple, chaque fois qu'une méthode annotée avec l'annotation @Bean est appelée, un nouvel objet Bean sera renvoyé. La valeur par défaut est vraie.

  • enforceUniqueMethods : ajouté à l'annotation @Configuration à partir de Spring 6.0, spécifiant si la méthode annotée avec l'annotation @Bean doit avoir un nom de méthode unique, la valeur est vraie ou fausse. Lorsque la valeur est vraie, cela signifie que les méthodes annotées avec les annotations @Bean ont des noms de méthode uniques et que ces noms de méthodes ne se chevauchent pas. Lorsque la valeur est fausse, cela signifie que les noms de méthodes annotés avec l'annotation @Bean ne sont pas uniques et qu'il y a un risque de chevauchement. La valeur par défaut est vraie.

Il ressort également du code source de l'annotation @Configuration que l'annotation @Configuration est essentiellement une annotation @Component, donc la classe de configuration elle-même annotée avec l'annotation @Configuration sera également enregistrée dans le conteneur IOC. . Dans le même temps, l'annotation @Configuration sera également analysée par l'annotation @ComponentScan.

2. Scénarios d'utilisation de @Configuration

Lors du développement d'une application basée sur les annotations Spring, vous pouvez annoter l'annotation @Configuration dans une certaine classe. Lorsqu'une classe est annotée avec l'annotation @Configuration, cela signifie que la classe est une classe de configuration. Vous pouvez utiliser l'annotation @Bean dans cette classe pour injecter des objets Bean dans le conteneur IOC. Vous pouvez également utiliser @Autowired, @Inject et. Annotations @Resource à injecter. L'objet Bean requis.

Remarque : lors du développement d'une application basée sur le mode d'annotation de Spring, lorsque vous utilisez la classe AnnotationConfigApplicationContext pour créer un conteneur IOC, vous devez faire attention aux points suivants :

(1) Si vous appelez le constructeur de la variable de type Class paramètre dans la classe AnnotationConfigApplicationContext, pour créer un conteneur IOC, cela signifie que l'objet Class de la classe de configuration annoté avec l'annotation @Configuration est transmis pour créer le conteneur IOC. L'annotation @Configuration annotée sur la classe de configuration peut être omise.
Si l'annotation @Configuration est omise sur la classe de configuration entrante, un objet d'instance Bean différent sera renvoyé chaque fois qu'une méthode annotée avec l'annotation @Bean dans la classe de configuration est appelée.

Le code source du constructeur qui passe les paramètres de variable de type Class dans la classe AnnotationConfigApplicationContext est le suivant :

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

(2) Si le constructeur qui passe les paramètres de variable de type String dans la classe AnnotationConfigApplicationContext est appelé pour créer un conteneur IOC , cela signifie passer Si vous entrez le nom du package de l'application pour créer un conteneur IOC, l'annotation @Configuration marquée sur la classe de configuration ne peut pas être omise.

Le code source du constructeur qui passe les paramètres des variables de type String dans la classe AnnotationConfigApplicationContext est le suivant :

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

3. Cas d'utilisation

1 Vérifier le rôle de l'attribut proxyBeanMethods

L'attribut proxyBeanMethods peut prendre une valeur. du vrai ou du faux. Lorsque la valeur est vraie, quel que soit le nombre d'appels de la méthode annotée avec l'annotation @Bean dans la classe annotée avec l'annotation @Configuration, le même objet Bean sera renvoyé. Lorsque la valeur est fausse, chaque fois qu'une méthode annotée avec l'annotation @Bean est appelée dans une classe annotée avec l'annotation @Configuration, un objet Bean différent sera renvoyé.

1.1 Vérifiez que la valeur proxyBeanMethods est vraie

(1) Créez la classe Person

La classe Person est principalement utilisée pour s'inscrire dans le conteneur IOC et instancier des objets.

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

(2) Créer une classe 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

Vous pouvez voir à partir des informations sur le résultat de sortie que le résultat de sortie indiquant si personne1 est égal à personne2 est vrai. Encore une fois, lors de l'appel de la méthode constructeur de la classe AnnotationConfigApplicationContext et en transmettant le nom du package pour créer un conteneur IOC, la @Configuration. l'annotation sur la classe de configuration ne peut pas être omise.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer