【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才会生效。




相关推荐
职教育人1 小时前
金砖软件测试赛项之Jmeter如何录制脚本!
java·测试工具·jmeter·性能优化·集成测试
码农小野3 小时前
基于SpringBoot的自习室预订系统
java·spring boot·后端
lizi888884 小时前
单组件的编写
java
java_heartLake4 小时前
设计模式之代理模式
java·设计模式·代理模式
深蓝海拓4 小时前
迭代器和生成器的学习笔记
笔记·python·学习
魏 无羡4 小时前
pgsql 分组查询方法
java·服务器·数据库
兩尛5 小时前
java--面向对象编程(中级部分)
java·开发语言
Xxxx. .Xxxx5 小时前
C语言程序设计实验与习题指导 (第4版 )课后题-第二章+第三章
java·c语言·开发语言
姜西西_5 小时前
[Spring]Spring MVC 请求和响应及用到的注解
java·spring·mvc
逸狼5 小时前
【JavaEE初阶】多线程6(线程池\定时器)
java·开发语言·算法