>Java >java지도 시간 >Java에서 @Configuration의 사용 시나리오는 무엇입니까?

Java에서 @Configuration의 사용 시나리오는 무엇입니까?

PHPz
PHPz앞으로
2023-04-21 10:37:191864검색

1. 간략한 소개

@Configuration 주석은 클래스에 주석을 달 수 있습니다. Spring을 시작하면 @Configuration 주석이 달린 클래스를 자동으로 스캔하여 IOC 컨테이너에 등록하고 인스턴스화합니다. 콩 개체.
@Configuration 주석이 달린 클래스에 @Bean 주석이 달린 특정 클래스 객체를 생성하는 메서드가 포함되어 있으면 Spring도 자동으로 @Bean 주석이 달린 메서드를 실행하고 해당 Bean 정의 정보를 IOC 컨테이너에 등록합니다. 인스턴스화합니다.

2. Annotation 설명

@Configuration 어노테이션은 Spring이 어노테이션 기반 개발을 지원할 수 있도록 Spring 3.0부터 추가된 어노테이션 유형 어노테이션으로 주로 클래스에 어노테이션을 작성하는 데 사용됩니다. 클래스에 @Configuration 주석이 표시되면 해당 클래스가 Spring 구성 클래스라는 의미입니다. @Configuration 주석은 Spring의 applicationContext.xml 파일을 대체할 수 있으며 @Configuration 주석으로 표시된 클래스는 자동으로 IOC 컨테이너에 등록되고 인스턴스화될 수 있습니다.

1. @Configuration 소스 코드

소스 코드에 대한 자세한 내용은 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;
}

@Configuration 주석의 각 속성의 의미는 다음과 같습니다.

  • value: Spring IOC 컨테이너에 저장된 Bean의 ID입니다.

  • proxyBeanMethods: Spring 5.2부터 @Configuration 주석에 추가되어 @Configuration 주석이 달린 구성 클래스가 프록시될 것인지 여부와 구성 클래스에서 @Bean 주석을 사용하여 생성된 Bean 객체가 IOC 컨테이너 싱글톤 개체, 값은 true 또는 false입니다. 값이 true이면 전체(전역) 모드를 나타냅니다. 이 모드에서는 구성 클래스에서 @Bean 주석을 사용하여 IOC 컨테이너에 주석이 달린 구성 클래스가 프록시됩니다. @Bean 주석이 표시된 메소드를 몇 번 호출하더라도 동일한 Bean 객체가 반환됩니다. 값이 false이면 라이트(경량) 모드를 나타냅니다. 이 모드에서는 @Configuration 주석이 달린 구성 클래스가 구성 클래스의 @Bean 주석을 사용하여 IOC 컨테이너에 주입되지 않습니다. 예제 모드에서는 @Bean 주석이 달린 메소드가 호출될 때마다 새로운 Bean 객체가 반환됩니다. 기본값은 true입니다.

  • enforceUniqueMethods: Spring 6.0부터 @Configuration 주석에 추가되어 @Bean 주석으로 주석이 달린 메서드가 고유한 메서드 이름을 가져야 하는지 여부를 지정하며 값은 true 또는 false입니다. 값이 true인 경우 @Bean 주석이 달린 메소드는 고유한 메소드 이름을 가지며 이러한 메소드 이름이 겹치지 않음을 의미합니다. 값이 false인 경우 @Bean 주석이 달린 메소드 이름이 고유하지 않으며 중복될 위험이 있음을 의미합니다. 기본값은 true입니다.

@Configuration 주석의 소스 코드에서도 @Configuration 주석이 본질적으로 @Component 주석임을 알 수 있으므로 @Configuration 주석이 달린 구성 클래스 자체도 IOC 컨테이너에 등록됩니다. . 동시에 @Configuration 주석도 @ComponentScan 주석으로 검사됩니다.

2. @Configuration 사용 시나리오

Spring 주석을 기반으로 애플리케이션을 개발할 때 특정 클래스에 @Configuration 주석을 달 수 있습니다. 클래스에 @Configuration 주석이 추가되면 해당 클래스가 구성 클래스라는 의미입니다. 이 클래스에서 @Bean 주석을 사용하여 IOC 컨테이너에 Bean 객체를 주입할 수도 있습니다. 주입할 @Resource 주석. 필수 Bean 객체입니다.

참고: Spring의 주석 모드를 기반으로 애플리케이션을 개발할 때 AnnotationConfigApplicationContext 클래스를 사용하여 IOC 컨테이너를 생성할 때 다음 사항에 주의해야 합니다.

(1) Class 유형 변수의 생성자를 호출하는 경우 AnnotationConfigApplicationContext 클래스의 매개변수, IOC 컨테이너를 생성하려면 @Configuration 주석이 달린 구성 클래스의 Class 객체를 전달하여 구성 클래스에 주석이 달린 @Configuration 주석을 생략할 수 있음을 의미합니다.
수신되는 구성 클래스에서 @Configuration 주석이 생략되면 구성 클래스에서 @Bean 주석이 달린 메서드가 호출될 때마다 다른 Bean 인스턴스 객체가 반환됩니다.

AnnotationConfigApplicationContext 클래스에 Class 유형의 변수 매개변수를 전달하는 생성자의 소스코드는 다음과 같다.

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

(2) AnnotationConfigApplicationContext 클래스에 String 유형의 변수 매개변수를 전달하는 생성자를 호출하여 IOC 컨테이너를 생성하는 경우 , 통과한다는 의미입니다. IOC 컨테이너를 생성하기 위해 애플리케이션의 패키지 이름을 입력하는 경우 구성 클래스에 표시된 @Configuration 주석을 생략할 수 없습니다.

AnnotationConfigApplicationContext 클래스에서 문자열 유형 변수 매개변수를 전달하는 생성자의 소스 코드는 다음과 같습니다.

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

3. 사용 사례

1.proxyBeanMethods 속성의 역할을 확인합니다.

proxyBeanMethods 속성은 값을 가질 수 있습니다. 참 또는 거짓. 값이 true인 경우 @Configuration 주석이 붙은 클래스에서 @Bean 주석이 붙은 메소드를 몇 번 호출해도 동일한 Bean 객체가 반환됩니다. 값이 false인 경우 @Configuration 주석이 달린 클래스에서 @Bean 주석이 달린 메서드가 호출될 때마다 다른 Bean 객체가 반환됩니다.

1.1 ProxyBeanMethods 값이 true인지 확인

(1) Person 클래스 생성

Person 클래스는 주로 IOC 컨테이너에 등록하고 객체를 인스턴스화하는 데 사용됩니다.

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

(2) 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

person1이 person2와 같은지 여부에 대한 출력 결과가 true임을 출력 결과 정보에서 확인할 수 있습니다. 다시 AnnotationConfigApplicationContext 클래스의 생성자 메서드를 호출하고 패키지 이름을 전달하여 IOC 컨테이너를 생성할 때 @Configuration 구성 클래스의 주석은 생략할 수 없습니다.

위 내용은 Java에서 @Configuration의 사용 시나리오는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제