springboot配置文件与注解

配置注解

   Spring Boot中的配置注解非常多样,它们主要用于简化Spring应用的配置和开发过程。以下是一些主要的配置注解及其简要说明:

@SpringBootApplication:

   这是Spring Boot的核心注解,是一个组合注解,它包括了@Configuration、@EnableAutoConfiguration、@ComponentScan。这个注解用来开启Spring Boot的自动配置功能,让Spring Boot根据添加的jar依赖自动配置应用。

@Configuration

   @Configuration 是 Spring 框架中的一个核心注解,它用于定义配置类,这些配置类相当于传统的 XML 配置文件,但提供了更加类型安全和面向对象的配置方式。通过 @Configuration 注解的类可以包含 @Bean 注解的方法,这些方法将会被 Spring 容器在启动时自动扫描并调用,用于生成容器中的管理对象(Bean)。
使用场景

  1. 替代 XML 配置文件:在 Spring 应用中,传统上通过 XML 文件来配置 Bean。但随着 Java 配置的引入,开发者可以通过使用 @Configuration 和 @Bean 注解来替代 XML 配置文件,使配置更加灵活和强大。
  2. 组合配置:通过 @Configuration 注解的类可以轻松地组合和重用配置。你可以通过 @Import 注解来导入其他配置类,从而实现配置的模块化。
  3. 条件化配置:结合 @Conditional 系列注解(如 @ConditionalOnBean、@ConditionalOnProperty 等),@Configuration 注解的类可以基于特定的条件来决定是否创建某个 Bean。
    示例
    下面是一个简单的使用 @Configuration 和 @Bean 注解的示例:
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
  
@Configuration  
public class AppConfig {  
  
    @Bean  
    public MyService myService() {  
        return new MyServiceImpl();  
    }  
  
    // 其他 @Bean 方法...  
}  
  
class MyService {  
    // 类的实现...  
}  
  
class MyServiceImpl implements MyService {  
    // 具体的实现...  
}

   在这个例子中,AppConfig 类被 @Configuration 注解标记为配置类。它包含一个 @Bean 注解的方法 myService(),该方法将返回一个 MyService 接口的实现 MyServiceImpl 的实例。当 Spring 容器启动时,它会自动扫描到 @Configuration 注解的类,并调用其中的 @Bean 方法来生成并管理 Bean。

注意事项

  1. 非侵入式:使用 @Configuration 和 @Bean 注解进行配置时,不需要修改类的其他部分(如字段、构造函数或普通方法),这保持了类的原有结构和功能。
  2. 懒加载:默认情况下,Spring 容器中的 Bean 是单例的(Singleton),并且会在容器启动时就被创建。但是,如果你使用了如 @Lazy 注解等特定配置,可以实现 Bean 的懒加载。
  3. 性能考虑:虽然 Java 配置方式比 XML 配置更加灵活和强大,但在大型项目中,过多的 Java 配置类可能会增加应用的启动时间和内存消耗。因此,在使用时需要权衡利弊。

@EnableAutoConfiguration:

   @EnableAutoConfiguration 注解是 Spring Boot 中的一个核心注解,它告诉 Spring Boot 基于添加的 jar 依赖自动配置你的 Spring 应用。@EnableAutoConfiguration 会尝试根据你添加的 jar 依赖自动配置 Spring 应用。例如,如果 classpath 下存在 HSQLDB,并且你没有手动配置任何数据库连接 beans,Spring Boot 会自动配置内存数据库。

   然而,需要注意的是,从 Spring Boot 2.0 开始,@SpringBootApplication 注解包含了 @EnableAutoConfiguration,因此,在大多数 Spring Boot 应用中,你不需要显式地添加 @EnableAutoConfiguration。@SpringBootApplication 是一个方便的注解,它包含了 @Configuration、@EnableAutoConfiguration 和 @ComponentScan。

示例
   虽然通常不需要显式地使用 @EnableAutoConfiguration,但了解它的工作原理和如何被 @SpringBootApplication 包含是有帮助的。下面是一个简化的例子,展示了如果我们要显式使用 @EnableAutoConfiguration(尽管这不是典型的做法):

import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;  
import org.springframework.context.annotation.Configuration;  
  
@Configuration  
@EnableAutoConfiguration // 通常在 Spring Boot 应用中不需要显式添加  
public class MyApplication {  
  
    public static void main(String[] args) {  
        SpringApplication.run(MyApplication.class, args);  
    }  
  
    // 这里可以添加其他的 @Bean 定义  
}

   在这个例子中,我们定义了一个名为 MyApplication 的配置类,并使用了 @Configuration 和 @EnableAutoConfiguration 注解。然而,正如前面提到的,我们通常会将这两个注解替换为 @SpringBootApplication,因为它已经包含了 @EnableAutoConfiguration 的功能,并且添加了 @ComponentScan 以确保 Spring Boot 能够扫描到其他的组件、配置和服务。

@ComponentScan:

   @ComponentScan 注解是 Spring 框架中的一个核心注解,它用于告诉 Spring 容器在哪个包(及其子包)中查找带有 @Component、@Service、@Repository、@Controller 等注解的类,并将这些类实例化为 Spring 容器中的 Bean。这样,Spring 就可以管理这些 Bean,包括它们的生命周期和依赖关系。

@ComponentScan 注解的基本用法

  1. value 或 basePackages 属性:指定要扫描的包路径。可以是单个包路径字符串,也可以是多个包路径组成的数组。
  2. basePackageClasses 属性:通过指定一个或多个类(位于要扫描的包或其子包中),来间接指定要扫描的包。这种方式可以避免硬编码包名,增加代码的可维护性。
  3. excludeFilters 和 includeFilters 属性:用于定制扫描过程,通过定义包含或排除的规则来精细控制哪些类应该被扫描并注册为 Bean。

示例
   假设我们有一个 Spring Boot 应用程序,我们希望 Spring 容器扫描 com.example.demo 包及其子包中的组件。

   通过 @SpringBootApplication 间接使用 @ComponentScan
在 Spring Boot 应用程序中,你通常不需要显式地使用 @ComponentScan,因为 @SpringBootApplication 已经包含了 @ComponentScan。但是,你可以通过 scanBasePackages 属性来定制扫描的包路径。

@SpringBootApplication(scanBasePackages = "com.example.demo")  
public class DemoApplication {  
  
    public static void main(String[] args) {  
        SpringApplication.run(DemoApplication.class, args);  
    }  
  
    // 通常情况下,这里的 scanBasePackages 可以省略,因为 Spring Boot 会默认扫描  
    // 带有 @SpringBootApplication 注解的类所在的包及其子包  
}

显式使用 @ComponentScan
虽然通常不需要显式使用 @ComponentScan,但了解如何在非 Spring Boot 应用程序或需要更精细控制时使用它仍然很重要。

@Configuration  
@ComponentScan(basePackages = "com.example.demo")  
public class AppConfig {  
    // 在这里,你可以定义更多的 Bean 或其他配置  
}  
  
// 然后在你的主类或其他配置类中导入这个配置  
@Import(AppConfig.class)  
public class DemoApplication {  
    // ...  
}

   但是,在 Spring Boot 应用程序中,你通常会使用 @SpringBootApplication 来代替上面的配置,因为它已经为你处理了配置类、自动配置和组件扫描。

注意
   当使用 @SpringBootApplication 时,默认情况下,Spring Boot 会扫描该注解所在类所在的包及其子包。因此,通常不需要显式指定 scanBasePackages 或 @ComponentScan。
   如果你有特殊的扫描需求(例如,扫描位于不同位置的包),那么你可能需要显式地使用 @ComponentScan 并设置其属性。
   自定义的扫描路径应该是 Spring Boot 应用程序启动类(带有 @SpringBootApplication 注解的类)的包的一个子集或完全不同的包,以避免意外的组件扫描行为。

@Value:

   用于将外部属性值注入到Spring Bean中。例如,可以注入application.properties或application.yml文件中的配置值。

   @Value 注解是 Spring 框架中用于注入配置文件中的值(如 properties 文件或 YAML 文件中的值)到 Bean 的字段中的。这个注解可以非常方便地将外部配置注入到你的应用程序中,而无需编写大量的样板代码。

基本用法
   @Value 注解可以应用于字段、setter 方法或配置方法上。当 Spring 容器启动时,它会查找与 @Value 注解中指定的占位符相匹配的属性,并将这些属性的值注入到相应的字段或方法中。

示例
假设你有一个 application.properties 文件,内容如下:

app.name=My Spring Boot Application  
app.description=This is a demo application for Spring Boot.

注入到字段
你可以使用 @Value 注解将 app.name 和 app.description 的值注入到 Spring Bean 的字段中。

import org.springframework.beans.factory.annotation.Value;  
import org.springframework.stereotype.Component;  
  
@Component  
public class AppConfig {  
  
    @Value("${app.name}")  
    private String appName;  
  
    @Value("${app.description}")  
    private String appDescription;  
  
    // 你可以添加 getter 和 setter 方法,但在这个例子中我们直接访问字段  
    public String getAppName() {  
        return appName;  
    }  
  
    public String getAppDescription() {  
        return appDescription;  
    }  
}

注入到 setter 方法
虽然字段注入是更常见的做法,但你也可以将 @Value 注解应用于 setter 方法。


import org.springframework.beans.factory.annotation.Value;  
import org.springframework.stereotype.Component;  
  
@Component  
public class AppConfig {  
  
    private String appName;  
    private String appDescription;  
  
    @Value("${app.name}")  
    public void setAppName(String appName) {  
        this.appName = appName;  
    }  
  
    @Value("${app.description}")  
    public void setAppDescription(String appDescription) {  
        this.appDescription = appDescription;  
    }  
  
    // getter 方法  
}

注意:虽然技术上可以将 @Value 注解应用于 setter 方法,但这种做法并不常见,因为字段注入通常更简单且易于理解。

注入到配置方法
在基于 Java 的配置类中,你还可以使用 @Value 注解来注入值到配置方法返回的 Bean 中。但是,这通常不是将值注入到字段或 setter 方法的直接替代方案,而是用于更复杂的配置场景。

注意事项
   确保你的配置文件(如 application.properties 或 application.yml)位于 Spring Boot 应用程序的类路径中,以便 Spring 能够加载这些配置。
   如果你的属性名包含特殊字符(如点号.),你可能需要使用 Spring 的表达式语言(SpEL)来引用它们,例如 @Value(“#{‘${some.prefix.property}’.concat(‘suffix’)}”)。但在大多数情况下,简单的 ${property.name} 语法就足够了。
   你可以使用 @PropertySource 注解来指定额外的属性文件,这些文件将被添加到 Spring 的环境属性中。但是,请注意,@PropertySource 通常与 @Configuration 类一起使用,而不是与 @Component 类一起使用。

@ConfigurationProperties:

   用于将外部配置文件中的属性绑定到Java Bean上,这是一种批量注入配置的方式,比@Value更加灵活和强大。
   @ConfigurationProperties 注解是 Spring Boot 提供的一种用于将配置文件中的属性绑定到 Java Bean 上的机制。与 @Value 注解相比,@ConfigurationProperties 提供了一种更加类型安全的方式来处理配置。它还可以支持复杂的类型,如列表和映射,以及嵌套属性。

基本用法

  1. 创建一个配置类:首先,你需要创建一个 Java 类,并使用 @ConfigurationProperties 注解来指定配置的前缀。
  2. 启用配置绑定:然后,你需要在 Spring Boot 的配置类(通常是一个带有 @SpringBootApplication 或 @EnableAutoConfiguration 注解的类)上添加 @EnableConfigurationProperties 注解(虽然对于 @Component 或 @Configuration 注解的类,这不是必需的,因为 Spring Boot 会自动检测到它们)。但是,如果你希望 Spring Boot 之外的类(比如第三方库中的类)也支持 @ConfigurationProperties,那么你就需要显式地添加 @EnableConfigurationProperties。
  3. 使用配置类:最后,你可以像使用其他 Spring Bean 一样使用配置类。
    示例
    假设我们有一个 application.properties 文件,内容如下:
myapp.name=My Spring Boot Application  
myapp.description=This is a demo application for Spring Boot.  
myapp.settings.first-name=John  
myapp.settings.last-name=Doe  
myapp.settings.enabled=true

创建配置类
   我们可以使用 @ConfigurationProperties 注解来创建一个 Java 类,该类将包含与上述属性相对应的字段。

import org.springframework.boot.context.properties.ConfigurationProperties;  
import org.springframework.stereotype.Component;  
  
@Component  
@ConfigurationProperties(prefix = "myapp")  
public class MyAppProperties {  
  
    private String name;  
  
    private String description;  
  
    private Settings settings = new Settings();  
  
    // Getter 和 Setter  
  
    public static class Settings {  
        private String firstName;  
        private String lastName;  
        private boolean enabled;  
  
        // Getter 和 Setter  
    }  
  
    // Getter 和 Setter 省略  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    // 其他字段的 Getter 和 Setter  
    // ...  
  
    // Settings 类的 Getter 和 Setter  
    public Settings getSettings() {  
        return settings;  
    }  
  
    public void setSettings(Settings settings) {  
        this.settings = settings;  
    }  
}

使用配置类
   现在,MyAppProperties 类中的字段已经被自动填充了 application.properties 文件中对应属性的值。你可以像使用其他 Spring Bean 一样,通过自动装配来使用它。

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Component;  
  
@Component  
public class MyAppComponent {  
  
    private final MyAppProperties myAppProperties;  
  
    @Autowired  
    public MyAppComponent(MyAppProperties myAppProperties) {  
        this.myAppProperties = myAppProperties;  
        // 现在你可以使用 myAppProperties 中的属性了  
    }  
  
    // 其他方法...  
}

注意
   如果你使用的是 Spring Boot 1.5 或更高版本,并且你的配置类位于主应用程序类(带有 @SpringBootApplication 注解的类)所在的包或其子包中,那么你就不需要显式地添加 @EnableConfigurationProperties 注解。Spring Boot 会自动扫描并绑定这些属性。
   @ConfigurationProperties 还提供了校验功能(通过 JSR-303 注解),以及将配置值转换为不同类型(如 Duration)的能力。
   在生产环境中,通常建议使用 .yaml 文件而不是 .properties 文件来管理配置,因为 .yaml 文件支持更复杂的结构和注释。但是,@ConfigurationProperties 可以与这两种格式的配置文件一起工作。

@PropertySource:

   指定外部属性文件的位置,这些文件会被Spring容器加载并解析。
   @PropertySource 注解是 Spring Framework 中的一个注解,用于指定外部属性文件的位置,该文件中的属性可以被 @Value 或 @ConfigurationProperties 注解所引用。这个注解通常用在配置类上,以便加载非标准位置(如不在类路径下的)的属性文件。

基本用法
   指定属性文件位置:使用 @PropertySource 注解的 value 或 locations 属性来指定属性文件的位置。可以使用类路径资源(classpath:)前缀来指定类路径下的文件,或者使用文件系统路径(file:)前缀来指定文件系统上的文件。
   使用 @Value 或 @ConfigurationProperties:在配置类或组件中,使用 @Value 注解来注入属性文件中定义的单个属性值,或者使用 @ConfigurationProperties 注解来绑定一组属性。
示例
   假设我们有一个位于类路径下的 app.properties 文件,内容如下:

app.name=My Spring App  
app.version=1.0

使用 @PropertySource 和 @Value
   首先,我们创建一个配置类,并使用 @PropertySource 注解来指定 app.properties 文件的位置。然后,我们使用 @Value 注解来注入属性值。

import org.springframework.beans.factory.annotation.Value;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.context.annotation.PropertySource;  
  
@Configuration  
@PropertySource("classpath:app.properties")  
public class AppConfig {  
  
    @Value("${app.name}")  
    private String appName;  
  
    @Value("${app.version}")  
    private String appVersion;  
  
    // Getter 方法  
    public String getAppName() {  
        return appName;  
    }  
  
    public String getAppVersion() {  
        return appVersion;  
    }  
  
    // 可以在这里添加更多的 Bean 定义或配置方法  
}

使用 @PropertySource 和 @ConfigurationProperties
   虽然 @PropertySource 通常与 @Value 一起使用,但你也可以将其与 @ConfigurationProperties 结合使用,尽管这不是其最常见的用法(因为 @ConfigurationProperties 通常自动扫描类路径下的属性文件)。然而,如果你需要加载非标准位置的属性文件,并且希望使用 @ConfigurationProperties 提供的复杂绑定特性,你可以这样做:

首先,定义一个配置类来绑定属性:

import org.springframework.boot.context.properties.ConfigurationProperties;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.context.annotation.PropertySource;  
  
@Configuration  
@PropertySource("classpath:app.properties")  
@ConfigurationProperties(prefix = "app")  
public class AppProperties {  
  
    private String name;  
    private String version;  
  
    // Getter 和 Setter  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public String getVersion() {  
        return version;  
    }  
  
    public void setVersion(String version) {  
        this.version = version;  
    }  
}

   注意:实际上,当使用 @ConfigurationProperties 时,你通常不需要显式地添加 @PropertySource,因为 Spring Boot 会自动从类路径下(包括 META-INF/spring-configuration-metadata.json 指定的位置)的 application.properties 或 application.yml 文件中加载匹配的属性。然而,如果你需要加载非标准位置的属性文件,并且想要利用 @ConfigurationProperties 的功能,你可以像上面那样做,但请记住,你还需要在 Spring Boot 的主类或配置类上添加 @EnableConfigurationProperties 注解(尽管对于带有 @Component 或 @Configuration 注解的类,这通常不是必需的)。

   在上面的示例中,由于我们显式地添加了 @PropertySource,因此 AppProperties 类将能够加载并绑定 app.properties 文件中的 app.name 和 app.version 属性,而无需任何额外的配置。然而,请注意,这个用法可能不是 @ConfigurationProperties 的典型用法,它更常用于自动绑定 application.properties 或 application.yml 文件中的属性。

@Conditional 及其派生注解(如@ConditionalOnClass、@ConditionalOnBean等):

   根据条件动态添加或排除Bean的装配。这些注解提供了一种强大的机制来在特定条件下激活或禁用Bean的创建。
   @Conditional 注解是 Spring Framework 中的一个强大功能,它允许在特定的条件下创建 bean。这意味着只有在满足特定条件时,相应的 bean 才会被注册到 Spring 应用上下文中。这个注解经常与 @Configuration 注解一起使用在配置类中,以定义条件化的 bean 配置。

   @Conditional 本身是一个元注解,它用于定义其他条件注解,这些条件注解随后可以被用在 @Bean 方法上。但是,Spring Boot 提供了一系列预定义的 @Conditional 注解,如 @ConditionalOnClass、@ConditionalOnMissingClass、@ConditionalOnBean、@ConditionalOnMissingBean、@ConditionalOnProperty 等,这些注解覆盖了大多数常见的条件场景。

示例
   下面是一个使用 @ConditionalOnProperty 注解的示例,该注解允许基于特定的环境属性来决定是否创建 bean。

   假设我们有一个配置类,我们想要根据 app.feature.enabled 属性的值来决定是否创建一个特定的服务(Service)bean。

   首先,我们在 application.properties 文件中设置属性:

# 启用或禁用特性  
app.feature.enabled=true

   然后,我们创建一个配置类,并使用 @ConditionalOnProperty 注解来条件化地创建 bean:

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
  
@Configuration  
public class ConditionalConfig {  
  
    @Bean  
    @ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true")  
    public MyFeatureService myFeatureService() {  
        return new MyFeatureService();  
    }  
  
    // MyFeatureService 是一个普通的类,实现了某个服务接口  
    static class MyFeatureService {  
        // 类的实现...  
    }  
}

   在这个例子中,只有当 app.feature.enabled 属性的值为 true 时,myFeatureService 方法才会被调用,MyFeatureService 的实例才会被创建并注册到 Spring 容器中。如果 app.feature.enabled 的值为 false 或该属性未设置,则 MyFeatureService 的实例不会被创建。

使用自定义条件
   除了使用 Spring Boot 提供的预定义条件注解外,你还可以创建自定义的条件注解。这涉及到实现 Condition 接口,并在你的自定义注解上使用 @Conditional 元注解来引用你的条件实现。但是,这通常更复杂,并且只在你需要非常特定的条件时才需要。

结论
   @Conditional 注解为 Spring 应用提供了灵活的 bean 创建条件,使得你可以根据各种条件(如类路径上的类、bean 的存在性、环境属性等)来启用或禁用特定的 bean 配置。这使得你的应用更加灵活和可配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值