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




相关推荐
xlsw_5 分钟前
java全栈day21--Web后端实战之利用Mybaits查询数据
java·开发语言
什么想法都无19 分钟前
stream
java·java stream
m0_7482336420 分钟前
WebService简介
java
love静思冥想20 分钟前
Stream `Collectors.toList()` 和 `Stream.toList()` 的区别(Java)
java·stream
Ch.yang39 分钟前
【Spring】 Bean 注入 HttpServletRequest 能保证线程安全的原理
java·spring·代理模式
web1508509664140 分钟前
基于Mysql、JavaScript、PHP、ajax开发的MBTI性格测试网站(前端+后端)
java
昙鱼1 小时前
springboot创建web项目
java·前端·spring boot·后端·spring·maven
eternal__day1 小时前
数据结构(哈希表(中)纯概念版)
java·数据结构·算法·哈希算法·推荐算法
天之涯上上1 小时前
JAVA开发 在 Spring Boot 中集成 Swagger
java·开发语言·spring boot
2402_857583491 小时前
“协同过滤技术实战”:网上书城系统的设计与实现
java·开发语言·vue.js·科技·mfc