【spring】@Profile注解学习

@Profile介绍

在Spring框架中,@Profile注解用于根据特定的配置文件来有条件地激活或禁用Bean的定义。这在开发和测试过程中非常有用,因为它允许你为不同的环境(如开发、测试、生产)定义不同的配置。

@Profile不仅可以标注在方法上,也可以标注在配置类上。如果标注在配置类上,只有在指定的环境时,整个配置类里面的所有配置才会生效。如果一个Bean上没有使用@Profile注解进行标注,那么这个Bean在任何环境下都会被注册到IOC容器中。

@Profile源码

java 复制代码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {
	String[] value();
}
源代码截图

@Profile属性介绍

  • value:指定环境的标识。

@Profile注解使用场景

1. 多环境配置

在实际开发过程中,通常会有开发、测试和生产等多个不同的运行环境。每个环境都有其特定的配置需求,如数据库连接信息、服务器地址等。通过使用@Profile注解,可以为不同的环境定义专属的配置类,从而实现多环境的灵活切换和管理。

2. 条件化Bean创建

有时候,某些Bean可能只在特定的条件下需要被创建。例如,你可能需要在测试环境中创建一些用于测试的辅助Bean,而在生产环境中则不需要。利用@Profile注解,可以仅在满足特定条件时创建这些Bean。

3. 功能开关

在某些情况下,可能需要根据环境或条件启用或禁用某些功能。通过@Profile注解,可以在配置类或者Bean定义的方法上设置条件,从而实现功能的动态开关。

4. 环境特定的安全性配置

安全性配置往往根据环境的不同而有所差异。例如,在开发环境中,可能需要关闭某些安全检查以便于调试;而在生产环境中,则需要开启所有的安全措施。使用@Profile注解可以对安全性相关的Bean进行条件化配置。

5. 集成测试环境配置

在进行集成测试时,可能需要一些专门为测试设计的配置,如模拟的外部服务、测试数据库等。通过为测试环境定义特定的Profile,并在其中包含相关的测试配置和Bean,可以方便地进行集成测试。

6. 动态配置

在运行时,可能需要根据外部条件(如系统属性、环境变量、命令行参数等)动态地改变应用程序的行为。@Profile注解可以结合这些动态输入来激活或禁用特定的配置。

7. 灰度发布

在进行灰度发布时,可能需要为一部分用户或服务器启用新的功能或配置,而其他用户或服务器则继续使用旧的配置。通过定义不同的Profile并根据用户或服务器的特征来激活相应的Profile,可以实现灰度发布的配置管理。

8. 性能监控与日志配置

在开发和测试环境中,通常需要开启详细的日志记录和性能监控,以便于发现和调试问题。而在生产环境中,则可能只需要记录关键的错误信息和性能指标。通过@Profile注解,可以根据环境来配置不同的日志级别和性能监控策略。

@Profile测试示例代码

示例代码 一
ProfileDemo类
java 复制代码
package com.yang.SpringTest.annotation.profileLearn;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>ProfileDemo类</p>
 *
 * @author By: chengxuyuanshitang
 * Package com.yang.SpringTest.annotation.profileLearn
 * Ceate Time 2024-04-09 17:37
 */
@Data
@Slf4j
public class ProfileDemo {

    private String environment;

    public ProfileDemo (String environment) {
        this.environment = environment;
    }
}
ProfileDemoConfig配置类
java 复制代码
package com.yang.SpringTest.annotation.profileLearn;

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

/**
 * <p>ProfileDemoConfig配置类</p>
 *
 * @author By: chengxuyuanshitang
 * Package com.yang.SpringTest.annotation.profileLearn
 * Ceate Time 2024-04-09 17:38
 */
//@Profile("development")
@Configuration
@ComponentScan(value = {"com.yang.SpringTest.annotation.profileLearn"})
public class ProfileDemoConfig {

    @Profile("development")
    @Bean("profileBeanDev")
    public ProfileDemo profileBeanDev(){
        return new ProfileDemo("开发环境");
    }
    @Profile("test")
    @Bean("profileBeanTest")
    public ProfileDemo profileBeanTest(){
        return new ProfileDemo("测试环境");
    }
    @Profile("production")
    @Bean("profileBeanProd")
    public ProfileDemo profileBeanProd(){
        return new ProfileDemo("生产环境");
    }
}
ProfileDemoTest测试类
java 复制代码
package com.yang.SpringTest.annotation.profileLearn;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * <p>ProfileDemoTest测试类</p>
 *
 * @author By: chengxuyuanshitang
 * Package com.yang.SpringTest.annotation.profileLearn
 * Ceate Time 2024-04-09 17:40
 */
@Slf4j
public class ProfileDemoTest {

    public static void main (String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext ();
        context.getEnvironment ().setActiveProfiles ("test");
        context.register (ProfileDemoConfig.class);
        context.refresh ();
        ProfileDemo demo = context.getBean (ProfileDemo.class);
        log.info ("ProfileDemo is : [ {} ]", demo);
    }
}
运行结果
示例代码 二

上面一样,在ProfileDemoConfig配置类填写@Profile("development")

ProfileDemoConfig配置类
java 复制代码
package com.yang.SpringTest.annotation.profileLearn;

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

/**
 * <p>ProfileDemoConfig配置类</p>
 *
 * @author By: chengxuyuanshitang
 * Package com.yang.SpringTest.annotation.profileLearn
 * Ceate Time 2024-04-09 17:38
 */
@Profile("development")
@Configuration
@ComponentScan(value = {"com.yang.SpringTest.annotation.profileLearn"})
public class ProfileDemoConfig {

    @Profile("development")
    @Bean("profileBeanDev")
    public ProfileDemo profileBeanDev(){
        return new ProfileDemo("开发环境");
    }
    @Profile("test")
    @Bean("profileBeanTest")
    public ProfileDemo profileBeanTest(){
        return new ProfileDemo("测试环境");
    }
    @Profile("production")
    @Bean("profileBeanProd")
    public ProfileDemo profileBeanProd(){
        return new ProfileDemo("生产环境");
    }
}
运行结果

出现错误No qualifying bean of type 'com.yang.SpringTest.annotation.profileLearn.ProfileDemo' available

修改ProfileDemoTest测试类

把setActiveProfiles ("test")

java 复制代码
package com.yang.SpringTest.annotation.profileLearn;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * <p>ProfileDemoTest测试类</p>
 *
 * @author By: chengxuyuanshitang
 * Package com.yang.SpringTest.annotation.profileLearn
 * Ceate Time 2024-04-09 17:40
 */
@Slf4j
public class ProfileDemoTest {

    public static void main (String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext ();
        context.getEnvironment ().setActiveProfiles ("development");
        context.register (ProfileDemoConfig.class);
        context.refresh ();
        ProfileDemo demo = context.getBean (ProfileDemo.class);
        log.info ("ProfileDemo is : [ {} ]", demo);
    }
}
运行结果

当@Profile注解标注到类上时,虽然类中的方法上也标注了@Profile注解,但是整体上会以类上标注的@Profile注解为准。如果设置的环境标识与类上标注的@Profile注解中的环境标识不匹配,则整个类中的配置都不会生效。否则,类中没有使用@Profile注解标识的Bean和环境标识与方法上使用@Profile注解指定的环境标识匹配的Bean才会生效。




相关推荐
在努力的前端小白12 分钟前
Spring Boot 敏感词过滤组件实现:基于DFA算法的高效敏感词检测与替换
java·数据库·spring boot·文本处理·敏感词过滤·dfa算法·组件开发
一叶飘零_sweeeet2 小时前
从繁琐到优雅:Java Lambda 表达式全解析与实战指南
java·lambda·java8
好望角雾眠3 小时前
第一阶段C#基础-10:集合(Arraylist,list,Dictionary等)
笔记·学习·c#
艾伦~耶格尔3 小时前
【集合框架LinkedList底层添加元素机制】
java·开发语言·学习·面试
星仔编程3 小时前
python学习DAY46打卡
学习
一只叫煤球的猫3 小时前
🕰 一个案例带你彻底搞懂延迟双删
java·后端·面试
最初的↘那颗心3 小时前
Flink Stream API 源码走读 - print()
java·大数据·hadoop·flink·实时计算
大霞上仙4 小时前
实现自学习系统,输入excel文件,能学习后进行相应回答
python·学习·excel
JH30734 小时前
Maven的三种项目打包方式——pom,jar,war的区别
java·maven·jar
带刺的坐椅5 小时前
轻量级流程编排框架,Solon Flow v3.5.0 发布
java·solon·workflow·flow·solon-flow