一文掌握SpringBoot注解之@Configuration知识文集(2)

在这里插入图片描述

作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。
多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。
欢迎 点赞✍评论⭐收藏

SpringBoot 领域知识

链接 专栏
SpringBoot 注解专业知识学习一 SpringBoot 注解专栏
SpringBoot 注解专业知识学习二 SpringBoot 注解专栏

文章目录

    • SpringBoot 注解 @Configuration 学习(2)
      • 11. 什么是配置属性(Configuration Properties)?如何在配置类中使用@ConfigurationProperties注解绑定配置属性?
      • 12. 如何在配置类中定义一个Spring Bean的作用域?
      • 13. @Primary注解的作用是什么?如何在配置类中使用它?
      • 14. @Lazy注解的作用是什么?如何在配置类中使用它?
      • 15. 如何在配置类中使用@Qualifier注解进行注入时的限定符匹配?
      • 16. 如何在配置类中使用@Value注解注入外部属性值?
      • 17. 什么是条件化Bean(Conditional Bean)?如何在配置类中定义一个条件化Bean?
      • 18. 如何在配置类中使用@PostConstruct和@PreDestroy注解初始化和销毁Bean?
      • 19. 什么是FactoryBean?如何在配置类中定义一个FactoryBean?
      • 20. 如何在配置类中使用SpEL表达式?它在Spring中的作用是什么?


SpringBoot 注解 @Configuration 学习(2)

一文掌握SpringBoot注解之@Configuration知识文集(2)_第1张图片


11. 什么是配置属性(Configuration Properties)?如何在配置类中使用@ConfigurationProperties注解绑定配置属性?

配置属性(Configuration Properties)是用于定义应用程序的配置选项的一种方式。它们可以用于管理应用程序的各种设置,如数据库连接信息、API密钥、端口号等。通过使用@ConfigurationProperties注解,可以将配置文件中的属性值自动绑定到配置类中的字段上,从而方便地引用这些配置属性。

在配置类中使用@ConfigurationProperties注解绑定配置属性的步骤如下:

  1. 创建一个配置类: 创建一个普通的Java类,通常使用@Component或者@Configuration注解来标记它作为配置类的身份。

  2. 为配置类添加@ConfigurationProperties注解: 在配置类上添加@ConfigurationProperties注解,并通过prefix属性指定配置属性的前缀(可选)。这个前缀将用于匹配配置文件中的属性名。

  3. 定义配置属性: 在配置类中添加与配置文件属性对应的字段,并提供相应的setter和getter方法。字段的名称与配置文件属性名称相匹配,或者可以使用@Value注解指定属性名(可选)。

  4. 将配置类注入到其他组件中: 使用@Autowired或者@Inject注解将配置类注入到其他组件中,可以直接引用配置属性。

下面是一个使用@ConfigurationProperties注解绑定配置属性的示例:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "myapp")
public class MyAppConfiguration {
   
    private String name;
    private String version;
    private int port;
   
    // setter and getter methods

    // ...

}

在上述示例中,通过@ConfigurationProperties注解将配置属性以 “myapp” 为前缀的属性绑定到MyAppConfiguration配置类中的字段上。对应的配置文件属性可以是myapp.namemyapp.versionmyapp.port

然后,可以将MyAppConfiguration注入到其他组件中,并使用其中的属性:

@Service
public class MyService {
   
    @Autowired
    private MyAppConfiguration myAppConfiguration;
    
    public void doSomething() {
        System.out.println(myAppConfiguration.getName());
        System.out.println(myAppConfiguration.getVersion());
        System.out.println(myAppConfiguration.getPort());
    }
}

在上述示例中,MyService通过@Autowired注解将MyAppConfiguration注入,并使用其中的属性。

需要注意的是,要使用@ConfigurationProperties注解,需要在项目的classpath中添加spring-boot-configuration-processor依赖,以支持自动提示和验证。

总结来说,通过@ConfigurationProperties注解,可以将配置文件中的属性值自动绑定到配置类中的字段上,方便地引用这些配置属性。要使用@ConfigurationProperties注解,需要创建一个配置类,并为其添加@ConfigurationProperties注解。然后,在其他组件中注入这个配置类,并使用其中的属性。


12. 如何在配置类中定义一个Spring Bean的作用域?

在配置类中定义Spring Bean的作用域可以通过在对应的方法上使用@Scope注解来实现,使用@Scope注解可以控制Bean的实例化和生命周期。

以下是在配置类中定义Spring Bean作用域的步骤:

  1. 创建一个配置类: 创建一个Java类,并使用@Configuration或者@Component注解来标记它作为配置类。

  2. 定义一个方法来创建Bean: 在配置类中定义一个方法,使用@Bean注解标记该方法为一个Bean的创建方法。

  3. 在@Bean注解中使用@Scope注解: 在@Bean注解上添加@Scope注解,并指定相应的作用域即可。@Scope注解的值可以是以下几种常见的作用域类型:

  • Singleton(默认): 在整个应用程序中共享一个实例。
  • Prototype:每次请求都创建一个新实例。
  • Request:在一个HTTP请求周期内共享一个实例。
  • Session:在一个用户会话中共享一个实例。
  • GlobalSession:在全局用户会话中共享一个实例。

以下是一个示例,展示了如何在配置类中定义作用域为Prototype的Spring Bean:

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

@Configuration
public class MyConfiguration {

    @Bean
    @Scope("prototype")
    public MyBean myBean() {
        return new MyBean();
    }
}

在上述示例中,使用@Scope注解在@Bean方法上指定作用域为"prototype",这将使得每次请求该Bean时都会创建一个新的实例。

需要注意的是,@Scope注解可以用于配置类中的@Bean方法,也可以用于普通的Bean定义方法上。如果在配置类中定义了多个方法返回同一个Bean类型的实例,并且这些方法上使用了不同的作用域注解,那么会根据作用域的优先级来选择合适的实例。

总结来说,可以通过在配置类中的@Bean方法上使用@Scope注解来定义Spring Bean的作用域。@Scope注解的值可以是Singleton、Prototype、Request、Session等。注意,作用域注解可以用于配置类中的@Bean方法,也可以用于普通的Bean定义方法上。


13. @Primary注解的作用是什么?如何在配置类中使用它?

@Primary注解的作用是在Spring容器中标记一个Bean作为首选的候选Bean。当存在多个候选Bean时,使用@Primary注解可以指定哪个Bean应该被优先选择。

以下是使用@Primary注解的步骤:

  1. 创建一个配置类: 创建一个Java类,并使用@Configuration或者@Component注解来标记它作为配置类。

  2. 定义多个候选Bean: 在配置类中定义多个方法,使用@Bean注解标记每个方法为一个Bean的创建方法。这些方法返回的对象将作为候选Bean。

  3. 在首选的候选Bean上使用@Primary注解: 在其中一个候选Bean的创建方法上添加@Primary注解,即可将其标记为首选的候选Bean。

以下是一个示例,展示了如何在配置类中使用@Primary注解:

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

@Configuration
public class MyConfiguration {

    @Bean
    public MyBean myBean1() {
        return new MyBean();
    }
    
    @Bean
    @Primary
    public MyBean myBean2() {
        return new MyBean();
    }
}

在上述示例中,定义了两个方法分别创建了两个MyBean类型的候选Bean。在其中一个方法上使用了@Primary注解,标记了myBean2()方法返回的对象为首选的候选Bean。

当需要注入MyBean类型的Bean时,如果没有特别指定要注入哪个Bean,那么Spring容器会选择具有@Primary注解的候选Bean。因此,在此示例中,如果在其他地方注入了MyBean类型的Bean,并且没有显式指定要注入哪个Bean,那么实际注入的将是myBean2()方法返回的对象。

需要注意的是,@Primary注解只能用于配置类中的@Bean方法上,不能用于普通的Bean定义方法或者其他注解上。同时,每个Bean类型只能有一个被标记为@Primary的Bean。

总结来说,使用@Primary注解可以在Spring容器中标记一个Bean为首选的候选Bean。在配置类中的@Bean方法上使用@Primary注解来指定首选的候选Bean,当注入该类型的Bean时,如果没有特别指定要注入哪个Bean,那么Spring容器会选择具有@Primary注解的候选Bean。


14. @Lazy注解的作用是什么?如何在配置类中使用它?

@Lazy注解的作用是延迟加载一个Bean。当使用@Lazy注解标记一个Bean时,Spring容器将在需要使用该Bean时才实例化它,而非在容器启动时就实例化。

以下是使用@Lazy注解的步骤:

  1. 创建一个配置类: 创建一个Java类,并使用@Configuration或者@Component注解来标记它作为配置类。

  2. 定义要延迟加载的Bean: 在配置类中定义一个方法,使用@Bean注解标记它为一个Bean的创建方法。

  3. 在Bean的创建方法上使用@Lazy注解: 在该方法上添加@Lazy注解,即可将该Bean标记为延迟加载的Bean。

以下是一个示例,展示了如何在配置类中使用@Lazy注解:

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

@Configuration
public class MyConfiguration {

    @Bean
    @Lazy
    public MyBean myBean() {
        return new MyBean();
    }

}

在上述示例中,使用@Lazy注解标记了myBean()方法,将MyBean标记为延迟加载的Bean。这意味着在容器启动时,并不会立即实例化这个Bean,而是在需要使用该Bean时才会进行实例化。

需要注意的是,@Lazy注解只能用于配置类中的@Bean方法上,不能用于普通的Bean定义方法或者其他注解上

总结来说,使用@Lazy注解可以延迟加载一个Bean,从而减少了容器启动时的资源占用。在配置类中的@Bean方法上使用@Lazy注解来指定要延迟加载的Bean。当需要使用该Bean时,Spring容器会在该时刻才实例化该Bean。


15. 如何在配置类中使用@Qualifier注解进行注入时的限定符匹配?

@Qualifier注解用于在使用@Autowired或者@Inject进行自动注入时,进行限定符匹配。它可以帮助解决当存在多个候选Bean时,容器无法确定要注入哪个Bean的问题。

以下是在配置类中使用@Qualifier注解的步骤:

  1. 创建一个配置类: 创建一个Java类,并使用@Configuration或者@Component注解来标记它作为配置类。

  2. 定义多个候选Bean: 在配置类中定义多个方法,使用@Bean注解标记每个方法为一个Bean的创建方法。这些方法返回的对象将作为候选Bean。

  3. 在注入的位置使用@Qualifier注解: 在需要进行限定符匹配的注入位置上使用@Qualifier注解,并指定对应的限定符名称。

以下是一个示例,展示了如何在配置类中使用@Qualifier注解:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfiguration {

    @Bean
    public MyBean myBean1() {
        return new MyBean();
    }
    
    @Bean
    @Qualifier("special")
    public MyBean myBean2() {
        return new MyBean();
    }

    @Autowired
    @Qualifier("special")
    private MyBean myBean;
}

在上述示例中,定义了两个方法分别创建了两个MyBean类型的候选Bean。其中,myBean2()方法使用@Qualifier(“special”)注解来指定了限定符名称为"special"。这意味着该Bean可以被唯一标识为"special"的限定符所匹配。

在最后的@Autowired注入位置上,使用@Qualifier(“special”)注解来指定要注入的限定符为"special"。这样,Spring容器就能够根据限定符进行正确的匹配,并注入对应的Bean。

需要注意的是,@Qualifier注解必须与@Autowired或者@Inject一起使用,其单独使用是没有效果的。

总结来说,使用@Qualifier注解可以在配置类中进行限定符匹配。在配置类中的@Bean方法上使用@Qualifier注解来对候选Bean进行限定符命名。在注入位置上使用@Qualifier注解来指定要注入的限定符名称,从而实现正确的限定符匹配。


16. 如何在配置类中使用@Value注解注入外部属性值?

@Value注解可用于在配置类中将外部属性值注入到Bean中。它可以帮助我们将配置文件中的属性值赋给相应的字段或者方法参数。

以下是在配置类中使用@Value注解进行属性值注入的步骤:

  1. 创建一个配置类: 创建一个Java类,并使用@Configuration或者@Component注解来标记它作为配置类。

  2. 声明一个字段或者方法参数: 在配置类中声明一个字段或者方法参数,用于接收外部的属性值。可以根据需要使用不同的注解来修饰这个字段或者方法参数,比如@Autowired或者@Inject。

  3. 在字段或者方法参数上使用@Value注解: 在字段或者方法参数上添加@Value注解,并指定要注入的属性值。属性值可以是直接的字符串,也可以是表达式。

以下是一个示例,展示了如何在配置类中使用@Value注解进行属性值注入:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfiguration {

    @Value("${myapp.name}")
    private String appName;
    
    @Value("${myapp.version}")
    private String appVersion;
    
    @Bean
    public MyBean myBean() {
        MyBean myBean = new MyBean();
        myBean.setName(appName);
        myBean.setVersion(appVersion);
        return myBean;
    }
}

在上述示例中,使用@Value注解将配置文件中的属性值注入到了appName和appVersion字段中。属性值通过${}来引用,其中的myapp.name和myapp.version分别是配置文件中的键。实际的属性值将从配置文件读取并赋给对应的字段。

需要注意的是,@Value注解必须与@Configuration或者@Component一起使用,其单独使用是没有效果的。

总结来说,使用@Value注解可以在配置类中将外部属性值注入到Bean中。在配置类中的字段或者方法参数上使用@Value注解来指定要注入的属性值,从而实现属性值的注入。


17. 什么是条件化Bean(Conditional Bean)?如何在配置类中定义一个条件化Bean?

条件化Bean(Conditional Bean)是指在特定条件满足时才会创建的Bean。这个特定条件可以是环境变量、系统属性、类的存在、Bean的存在或任何自定义的条件。

以下是在配置类中定义一个条件化Bean的步骤:

  1. 创建一个配置类: 创建一个Java类,并使用@Configuration注解将其标记为配置类。

  2. 定义一个@Bean方法: 在配置类中定义一个使用@Bean注解标记的方法,并在方法内部创建要条件化的Bean。

  3. 在@Bean方法上使用@Conditional注解: 在@Bean方法上添加@Conditional注解,条件的评估将在这里进行。该注解接受一个实现了Condition接口的类作为参数,用于判断是否满足条件。

以下是一个示例,展示了如何在配置类中定义一个条件化Bean:

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

@Configuration
public class MyConfiguration {

    @Bean
    @Conditional(MyCondition.class)
    public MyBean myBean() {
        return new MyBean();
    }
}

在上述示例中,使用@Conditional注解来定义了一个条件化Bean。它的参数是一个实现了Condition接口的类MyCondition,用于判断是否满足条件。如果满足条件,即MyCondition中的matches方法返回true,则会创建MyBean bean。否则,该bean将不会被创建。

需要注意的是,@Conditional注解必须与@Bean一起使用,其单独使用是没有效果的。

总结来说,条件化Bean是在特定条件满足时才会创建的Bean。我们可以在配置类中使用@Conditional注解来定义条件化Bean。该注解用于指定满足条件的判断逻辑,并与@Bean一起使用,从而实现条件化的Bean创建。


18. 如何在配置类中使用@PostConstruct和@PreDestroy注解初始化和销毁Bean?

在配置类中,我们可以使用@PostConstruct和@PreDestroy注解来定义Bean的初始化和销毁方法。

以下是在配置类中使用@PostConstruct和@PreDestroy注解的步骤:

  1. 创建一个配置类: 创建一个Java类,并使用@Configuration注解将其标记为配置类。

  2. 定义Bean: 在配置类中定义一个Bean,并且为其需要进行初始化或销毁操作的方法添加@PostConstruct或@PreDestroy注解。

  3. 在方法上使用@PostConstruct或@PreDestroy注解: 在初始化方法上使用@PostConstruct注解,在销毁方法上使用@PreDestroy注解。这些注解将指定这些方法为Bean的初始化方法和销毁方法。

以下是一个示例,展示了如何在配置类中使用@PostConstruct和@PreDestroy注解进行Bean的初始化和销毁:

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfiguration {

    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
    
    @PostConstruct
    public void init() {
        // 在Bean创建完成后执行一些初始化操作
    }
    
    @PreDestroy
    public void destroy() {
        // 在Bean销毁前执行一些清理操作
    }
}

在上述示例中,我们定义了一个初始化方法init()和一个销毁方法destroy(),并分别使用@PostConstruct和@PreDestroy注解进行标记。这样,在Bean创建完成后,init()方法会被自动调用进行初始化操作;在Bean销毁前,destroy()方法会被自动调用进行清理操作。

需要注意的是,@PostConstruct和@PreDestroy注解必须与@Configuration或者@Component一起使用,它们单独使用是没有效果的。

总结来说,在配置类中可以使用@PostConstruct和@PreDestroy注解来定义Bean的初始化和销毁方法。通过在方法上添加对应的注解,我们可以指定这些方法为Bean的初始化方法和销毁方法,在Bean创建完成后和销毁前自动调用它们。


19. 什么是FactoryBean?如何在配置类中定义一个FactoryBean?

FactoryBean 是一个特殊的 Bean,它的作用是产生或者包装其他的 Bean。FactoryBean 接口提供了一种更加灵活的方式来创建 Bean 实例,允许我们在实例化阶段执行自定义的逻辑。

以下是在配置类中定义一个 FactoryBean 的步骤:

1.创建一个实现了 FactoryBean 接口的类: 创建一个 Java 类,并实现 FactoryBean 接口。

import org.springframework.beans.factory.FactoryBean;

public class MyFactoryBean implements FactoryBean<MyBean> {

    @Override
    public MyBean getObject() throws Exception {
        // 在这里创建并返回 MyBean 的实例
        return new MyBean();
    }

    @Override
    public Class<?> getObjectType() {
        return MyBean.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

在上述示例中,我们实现了 FactoryBean 接口,并为其提供了 getObject() 方法来创建并返回 MyBean 实例。getObjectType() 方法返回 MyBean 的类型,isSingleton() 方法则指示这个 Bean 是否为单例。

2.在配置类中定义 FactoryBean: 在配置类中定义一个方法,并使用@Bean 注解将其标记为一个 Bean。

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

@Configuration
public class MyConfiguration {

    @Bean
    public FactoryBean<MyBean> myFactoryBean() {
        return new MyFactoryBean();
    }

}

在上述示例中,我们在配置类中定义了一个方法 myFactoryBean(),并为其添加了 @Bean 注解。这样,Spring 将会创建一个 FactoryBean 的实例,并将其注册为一个容器管理的 Bean。

需要注意的是,方法的返回类型必须是 FactoryBean 类型,而不是实际 Bean 的类型。在这个示例中,返回类型为 FactoryBean,而不是 MyBean。

总结来说,FactoryBean 是一个特殊的 Bean,它用于产生或者包装其他的 Bean。我们可以通过实现 FactoryBean 接口来定义一个 FactoryBean,然后在配置类中使用 @Bean 注解来创建 FactoryBean 的实例。这样,Spring 将会通过该 FactoryBean 来生成我们需要的 Bean 实例。


20. 如何在配置类中使用SpEL表达式?它在Spring中的作用是什么?

在配置类中使用 SpEL(Spring Expression Language)表达式可以让我们更加灵活地配置和管理 Spring 应用程序。SpEL 是一种强大的表达式语言,它可以在运行时计算值,用于配置和管理 Bean 的属性以及执行复杂的逻辑。

以下是在配置类中使用 SpEL 表达式的示例:

1.在 @Value 注解中使用 SpEL 表达式: 我们可以在配置类中使用 @Value 注解,并在括号中使用 SpEL 表达式来引用其他 Bean 的属性或调用方法。

@Configuration
public class MyConfiguration {

    @Value("#{myBean.name}")
    private String name;

    @Bean
    public MyBean myBean() {
        return new MyBean();
    }

    @Bean
    public OtherBean otherBean() {
        return new OtherBean(name);
    }
}

在上述示例中,我们通过 @Value 注解在配置类中使用了 SpEL 表达式 #{myBean.name},它引用了另一个 Bean myBean 的 name 属性的值。

2.在 @Conditional 注解中使用 SpEL 表达式: 我们可以在 @Conditional 注解中使用 SpEL 表达式来进行条件判断,决定是否应该创建某个 Bean。

@Configuration
public class MyConfiguration {

    @Bean
    @Conditional("#{systemProperties['os.name'].contains('Windows')}")
    public MyBean myBean() {
        return new MyBean();
    }
}

在上述示例中,我们使用了 SpEL 表达式 #{systemProperties[‘os.name’].contains(‘Windows’)},它判断系统的操作系统名称中是否包含 “Windows”,如果条件成立,则创建 MyBean。

3.在 @Configuration 注解中使用 SpEL 表达式: 我们可以在 @Configuration 注解中使用 SpEL 表达式来动态地决定是否加载某个配置类。

@Configuration
@ConditionalOnExpression("#{environment.getProperty('app.feature.enabled') == 'true'}")
public class MyConfiguration {
    //...
}

在上述示例中,我们使用了 SpEL 表达式 #{environment.getProperty(‘app.feature.enabled’) == ‘true’},它根据配置文件中的 app.feature.enabled 属性的值来决定是否加载该配置类。

总结来说,SpEL 是 Spring 中的一种表达式语言,它可以在配置类中使用 @Value、@Conditional、@Configuration 注解中来进行配置和管理。它的作用是让我们可以在运行时计算值,引用其他 Bean 的属性或调用方法,进行条件判断,动态地决定是否加载某个配置类等。使用 SpEL 表达式可以让我们的配置更加灵活和可配置。

一文掌握SpringBoot注解之@Configuration知识文集(2)_第2张图片

你可能感兴趣的:(SpringBoot专栏,Java基础学习,Java专栏,spring,boot,后端,java,spring,cloud,intellij-idea,maven,spring)