Exploring
首页
  • Java

    • 面向对象的思想OOP
    • 浅谈Java反射原理
    • endorsed覆盖JDK中的类
  • 认证与授权

    • LDAP概念和原理介绍
    • OAuth2介绍
  • Impala

    • Impala 介绍
  • MySQL

    • 关于MySQL的一些面试题
    • 解决MySQL不到中文数据
    • 数据库之事务与实现原理
  • Oracle

    • oracle的表空间,用户管理,表操作,函数
    • oracle的查询、视图、索引
    • plsql简单入门
  • Redis

    • 数据类型详解
    • 跳越表
    • 数据持久化的两种方式
  • 共识算法

    • gossip
  • RPC

    • GRPC初识与快速入门
    • ProtocolBuffer基本语法
  • RabbitMQ

    • RabbitMQ入门程序之HelloWorld
    • RabbitMQ之工作模式
  • Zookeeper

    • Zookeeper一文入门
  • Docker

    • Docker入门初体验
  • Maven

    • 把自己的包到Maven中央仓库
    • Maven之自定义插件
  • Nginx

    • nginx的安装
    • nginx的配置文件
    • nignx 的变量
  • Tomcat

    • Servlet3通过SPI进行注册组件
  • Vagrant

    • vagrant 初始化
    • vagrant 常用配置
    • vagrant 自己制作 box
  • Linux

    • 启动方式 Systemd
    • 后台服务
    • 防火墙与 Iptables
  • 设计模式

    • 设计模式-代理
    • 设计模式-单例模式
    • 设计模式-迭代器
  • 分布式

    • CAP 理论
  • 数据结构

    • 数据结构之堆Heap
    • 数据结构之哈希表
    • 数据结构之队列
  • 计算机网络

    • HTTP与HTTPS详解
    • 浅谈DNS协议
    • ISP中的网络层
  • 算法

    • 常用查找算法及Java实现
    • 常用排序算法及Java实现
    • 迪杰斯特拉算法
  • 操作系统

    • 操作系统之进程调度算法
    • 操作系统之进程通讯IPC
    • 操作系统之内存管理
  • 抓包

    • 生成安卓系统证书
  • 加解密

    • 常见加密算法
    • 公开秘钥基础知识
    • RSA 解析
  • Windows

    • scoop 包管理
    • windows-terminal 配置
    • 增强 PowerShell
归档
Github (opens new window)
首页
  • Java

    • 面向对象的思想OOP
    • 浅谈Java反射原理
    • endorsed覆盖JDK中的类
  • 认证与授权

    • LDAP概念和原理介绍
    • OAuth2介绍
  • Impala

    • Impala 介绍
  • MySQL

    • 关于MySQL的一些面试题
    • 解决MySQL不到中文数据
    • 数据库之事务与实现原理
  • Oracle

    • oracle的表空间,用户管理,表操作,函数
    • oracle的查询、视图、索引
    • plsql简单入门
  • Redis

    • 数据类型详解
    • 跳越表
    • 数据持久化的两种方式
  • 共识算法

    • gossip
  • RPC

    • GRPC初识与快速入门
    • ProtocolBuffer基本语法
  • RabbitMQ

    • RabbitMQ入门程序之HelloWorld
    • RabbitMQ之工作模式
  • Zookeeper

    • Zookeeper一文入门
  • Docker

    • Docker入门初体验
  • Maven

    • 把自己的包到Maven中央仓库
    • Maven之自定义插件
  • Nginx

    • nginx的安装
    • nginx的配置文件
    • nignx 的变量
  • Tomcat

    • Servlet3通过SPI进行注册组件
  • Vagrant

    • vagrant 初始化
    • vagrant 常用配置
    • vagrant 自己制作 box
  • Linux

    • 启动方式 Systemd
    • 后台服务
    • 防火墙与 Iptables
  • 设计模式

    • 设计模式-代理
    • 设计模式-单例模式
    • 设计模式-迭代器
  • 分布式

    • CAP 理论
  • 数据结构

    • 数据结构之堆Heap
    • 数据结构之哈希表
    • 数据结构之队列
  • 计算机网络

    • HTTP与HTTPS详解
    • 浅谈DNS协议
    • ISP中的网络层
  • 算法

    • 常用查找算法及Java实现
    • 常用排序算法及Java实现
    • 迪杰斯特拉算法
  • 操作系统

    • 操作系统之进程调度算法
    • 操作系统之进程通讯IPC
    • 操作系统之内存管理
  • 抓包

    • 生成安卓系统证书
  • 加解密

    • 常见加密算法
    • 公开秘钥基础知识
    • RSA 解析
  • Windows

    • scoop 包管理
    • windows-terminal 配置
    • 增强 PowerShell
归档
Github (opens new window)
  • Java

    • 基础

    • 并发与多线程

    • 日志系统

    • 单元测试

    • JVM

    • Spring

      • 理解依赖注入与松耦合
      • Spring-Aop-注解方式食用
      • spring给util类注入bean
      • Spring之Bean的生命周期
      • Spring之Bean的作用域
      • Spring中Profiles的作用及原理浅析
        • 什么是Profile
        • Spring中使用Profile的例子
        • 浅析源码
        • 激活Profile
      • SpringBoot中的服务端推送SSE
    • SpringBoot

    • 一些工具

  • 语言
  • Java
  • Spring
unclezs
2020-03-10
0
目录

Spring中Profiles的作用及原理浅析

# 什么是Profile

profile是用户区别环境来执行那些代码的,在我们日常开发中经常需要由开发环境到生产环境切换,这个时候需要更改数据库、redis等等这些的连接地址和密码,改完再打包,然后再改回来,这样实在是繁琐且多余。而Profile的作用正是解决这个问题的。

# Spring中使用Profile的例子

  1. 创建根据Profile配置的配置类
public class Message {
    private String message;
}

@Configuration
@Profile("dev")
public class DevConfig {
    @Bean
    Message message() {
        Message message = new Message();
        message.setMessage("dev env");
        return message;
    }
}

@Configuration
@Profile("pro")
public class ProConfig {
    @Bean
    Message message() {
        Message message = new Message();
        message.setMessage("pro env");
        return message;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  1. 测试根据激活的Profile来配置
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ContextConfig.class)
@ActiveProfiles("pro")
public class SpringTest {
    @Autowired
    private Message message;

    @Test
    public void testProfile(){
        System.out.println(message.getMessage());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

其中ContextConfiguration是指定包扫描的,里面就配置了ComponetScan @ActiveProfile是指定激活的Profile,值可以是数组 比如同时激活两个环境@ActiveProfile({"dev","pro"})

  1. 运行代码测试

# 浅析源码

用户标记在什么环境下启用,使用实示例@Profile("dev")。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {
	String[] value();
}

1
2
3
4
5
6
7
8

条件匹配,当满足条件的时候才使这个配置生效。value也得以证明是一个数组,可以传入多个profile,可以看到里面有一个@Conditional注解,可以跟进Conditional的源码看看

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional{
	Class<? extends Condition>[] value();
}
1
2
3
4
5
6

里面的需要传入实现了Condition接口,而再@Profile中的@Conditional里面传入了ProfileCondition.class,可以再看看ProfileCondition的源码

class ProfileCondition implements Condition {
	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
		if (attrs != null) {
			for (Object value : attrs.get("value")) {
				if (context.getEnvironment().acceptsProfiles(Profiles.of((String[]) value))) {
					return true;
				}
			}
			return false;
		}
		return true;
	}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

他实现了Condition接口,ConditionContext里面可以拿到当前环境的激活的Profile然后从AnnotatedTypeMetadata中拿到@Profile注解的value值,然后对比是否包含当前环境的Profile,如果有则返回true,条件生效。

# 激活Profile

激活方式是设置spring.profiles.active的值,可以是一个数组。也可以设置spring.profiles.default来指定默认激活的profile。 通常我们可以通过一下几种方式来改变profile

  • 在spring-web中通过DispatcherServlet传入spring.profiles.default,比如:
    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>spring.profiles.default</param-name>
            <param-value>dev</param-value>
        </init-param>
    </servlet>
1
2
3
4
5
6
7
8

在DispatcherServlet中可以通过super.getServletConfig().getInitParameter("spring.profiles.default")获取

  • 在web应用中使用context上下问参数来指定
    <context-param>
            <param-name>spring.profiles.default</param-name>
            <param-value>dev</param-value>
    </context-param>
1
2
3
4

在Servlet中可以通过getServletConfig().getServletContext().getInitParameter("spring.profiles.default")获取。

  • 作为JNDI条目,JDNI是Java 命名与目录接口(Java Naming and Directory Interface)
  • 作为环境变量,设置一个名字为spring.active.profile的环境变量
  • 作为JVM的参数,比如java -jar xxx.jar --spring.profile.active=dev
  • 在测试类中可以使用@ActiveProfiles注解指定
在 GitHub 编辑此页 (opens new window)
上次更新: 2024/02/25, 12:11:11
Spring之Bean的作用域
SpringBoot中的服务端推送SSE

← Spring之Bean的作用域 SpringBoot中的服务端推送SSE→

Theme by Vdoing | Copyright © 2018-2024 unclezs
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式