Home  >  Article  >  Java  >  What are the usage scenarios of @Configuration in Java?

What are the usage scenarios of @Configuration in Java?

PHPz
PHPzforward
2023-04-21 10:37:191802browse

1. Brief introduction

@Configuration annotation can be annotated on a class. When it is annotated on a class, Spring will automatically scan the class annotated with @Configuration annotation and register it in the IOC container. And be instantiated into a Bean object.
If the class annotated with @Configuration annotation contains a method to create a certain class object annotated with @Bean annotation, then Spring will also automatically execute the method annotated with @Bean annotation and register the corresponding Bean definition information in IOC container and instantiated.

2. Annotation description

@Configuration annotation is an annotation type annotation added since Spring 3.0 version that enables Spring to support annotation-driven development. It is mainly used for annotation on classes. When a class is marked with the @Configuration annotation, it means that this class is a Spring configuration class. The @Configuration annotation can replace Spring's applicationContext.xml file, and classes marked with the @Configuration annotation can be automatically registered to the IOC container and instantiated.

1. @Configuration source code

For source code details, see: 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;
}

The meaning of each attribute in the @Configuration annotation is as follows:

  • value: The id of the Bean stored in the Spring IOC container.

  • proxyBeanMethods: Added to the @Configuration annotation starting from Spring 5.2, indicating whether the configuration class annotated with the @Configuration annotation will be proxied, and generated using the @Bean annotation in the configuration class Whether the Bean object is a singleton object in the IOC container, the value is true or false. When the value is true, it indicates full (global) mode. In this mode, the configuration class annotated with @Configuration annotation will be proxied. The Bean object injected into the IOC container using @Bean annotation in the configuration class is singleton mode. No matter how many times you call a method marked with the @Bean annotation, the same Bean object is returned. When the value is false, it indicates lite (lightweight) mode. In this mode, the configuration class annotated with the @Configuration annotation will not be proxied. The Bean object injected into the IOC container using the @Bean annotation in the configuration class is not a single In the example mode, each time a method annotated with the @Bean annotation is called, a new Bean object will be returned. The default value is true.

  • enforceUniqueMethods: Added to the @Configuration annotation starting from Spring 6.0, specifying whether the method annotated with the @Bean annotation needs to have a unique method name, the value is true or false. When the value is true, it means that methods annotated with @Bean annotations have unique method names, and these method names do not overlap. When the value is false, it means that the method names annotated with the @Bean annotation are not unique and there is a risk of overlapping. The default value is true.

It can also be seen from the source code of the @Configuration annotation that the @Configuration annotation is essentially a @Component annotation, so the configuration class itself annotated with the @Configuration annotation will also is registered in the IOC container. At the same time, the @Configuration annotation will also be scanned by the @ComponentScan annotation.

2. @Configuration usage scenarios

When developing an application based on Spring annotations, you can annotate the @Configuration annotation to a certain class. When a class is annotated with the @Configuration annotation, it means that the class is a configuration class. You can use the @Bean annotation in this class to inject Bean objects into the IOC container. You can also use @Autowired, @Inject and @Resource annotations to inject. The required Bean object.

Note: When developing an application based on Spring's annotation mode, when using the AnnotationConfigApplicationContext class to create an IOC container, you need to pay attention to the following matters:

(1) If the call is passed in the AnnotationConfigApplicationContext class The constructor of Class type variable parameters is used to create an IOC container, which means that the Class object of the configuration class annotated with the @Configuration annotation is passed in to create the IOC container. The @Configuration annotation annotated on the configuration class can be omitted.
If the @Configuration annotation is omitted on the incoming configuration class, a different Bean instance object will be returned each time a method annotated with the @Bean annotation in the configuration class is called.

The source code of the constructor method that passes in Class type variable parameters in the AnnotationConfigApplicationContext class is as follows:

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

(2) If the constructor that passes in String type variable parameters in the AnnotationConfigApplicationContext class is called Method to create an IOC container, which means passing in the package name of the application to create an IOC container, the @Configuration annotation marked on the configuration class cannot be omitted.

The source code of the constructor that passes in String type variable parameters in the AnnotationConfigApplicationContext class is as follows:

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

3. Use cases

1. Verify the role of the proxyBeanMethods attribute

The proxyBeanMethods attribute can take the value true or false. When the value is true, no matter how many times the method annotated with @Bean annotation in the class annotated with @Configuration annotation is called, the same Bean object will be returned. When the value is false, each time a method annotated with @Bean annotation is called in a class annotated with @Configuration annotation, a different Bean object will be returned.

1.1 Verify that the value of proxyBeanMethods is true

(1) Create the Person class

The Person class is mainly used to register in the IOC container and instantiate objects.

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

(2) Create ConfigurationAnnotationConfig class

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

As can be seen from the output result information, the output result of whether person1 is equal to person2 is true. Again, when calling the constructor method of the AnnotationConfigApplicationContext class and passing in the package name to create the IOC container, the @ on the configuration class cannot be omitted. Configuration annotation.

The above is the detailed content of What are the usage scenarios of @Configuration in Java?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete