Spring实战之JavaConfig方式多环境与profile配置
admin
2024-02-29 18:33:03
0

Spring实战之JavaConfig方式多环境与profile配置

  • 什么是多环境
  • 配置profile bean-@Profile注解在类级别上
    • 开发环境配置
    • 生产环境配置
  • 配置profile bean-@Profile注解在方法级别上
  • 如何激活profile

什么是多环境

以数据源为例,在不同环境下,我们会需要代码提供不同的数据源bean。如:

  • 开发环境:我们需要嵌入式数据库
  • 生产环境:我们需要使用JNDI从容器中获取一个Datasource
  • QA环境:我们需要配置DBCP连接池获取DataSource

如果我们通过修改代码的方式每次部署不同环境时就改一次对应的代码,你是不是会疯掉呢?(会!)
那怎么做能根据不同的环境来让我们的代码自动提供相应的数据源对象呢?

配置profile bean-@Profile注解在类级别上

通过Spring为环境相关的bean所提供的解决方案,是根据环境来决定该创建那个bean和不该创建那个bean。要注意的是,Spring并不是在构建的时候做出这样的决策,而是等到运行时再来确定

Spring引入了bean profile的功能。要使用profile,首先要将所有不同的bean定义到一个或多个profile之中,在将应用部署到每个环境时,还要确保对应的profile处于激活(active)的状态。

在Java配置中,可以使用@Profile注解指定某个bean属于哪一个profile。

开发环境配置

例如,在配置类中,嵌入式数据库的DataSource可能会配置成如下所示:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;import javax.sql.DataSource;@Configuration
@Profile("dev")
public class DevelopmentProfileConfig {@Beanpublic DataSource dataSource() {return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).addScript("classpath:schema.sql").addScript("classpath:test-data.sql").build();}
}

类上添加了@Profile注解,它会告诉Spring这个配置类中 的bean只有在dev profile激活时才会创建。如果dev profile 没有激活,那么该类中带有@Bean注解的方法都会被忽略。

生产环境配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jndi.JndiObjectFactoryBean;import javax.sql.DataSource;@Configuration
@Profile("prod")
public class ProductionProfileConfig {@Beanpublic DataSource dataSource() {JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();jndiObjectFactoryBean.setJndiName("jdbc/myDS");jndiObjectFactoryBean.setResourceRef(true);jndiObjectFactoryBean.setProxyInterface(DataSource.class);return (DataSource) jndiObjectFactoryBean.getObject();}
}

类上添加了@Profile注解,它会告诉Spring这个配置类中 的bean只有在prod profile激活时才会创建。

配置profile bean-@Profile注解在方法级别上

上面说了@Profile注解在类级别上,现在我们看看将@Profile注解在方法级别上,可以将多个bean的声明放到同一个配置类之中,更方便的进行代码阅读。如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.jndi.JndiObjectFactoryBean;import javax.sql.DataSource;@Configuration
@Profile("prod")
public class DataSourceConfig {/*** 为dev profile装配的bean*/@Bean@Profile("dev")public DataSource embeddedDataSource() {return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).addScript("classpath:schema.sql").addScript("classpath:test-data.sql").build();}/*** 为prod profile装配的bean*/@Bean@Profile("prod")public DataSource jndiDataSource() {JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();jndiObjectFactoryBean.setJndiName("jdbc/myDS");jndiObjectFactoryBean.setResourceRef(true);jndiObjectFactoryBean.setProxyInterface(DataSource.class);return (DataSource) jndiObjectFactoryBean.getObject();}
}

但是需要注意一点,尽管如上每个Datasource bean都被声明在一个配置类中,并且只有当规定的profile激活时,相应的bean才会被创建,但是在代码不断迭代开发的过程中,可能会有其他的bean并没有被开发人员声明在一个给定的profile范围内。对于没有指定profile的bean,它始终都会被创建,此类bean就与激活哪个profile没有关系了!

如何激活profile

Spring在确定哪个profile处于激活状态时,需要依赖两个独立的属性:
spring.profiles.activespring.profiles.default

  • 如果设置了spring.profiles.active属性的话,那它的值就用来确定激活哪个profile;
  • 如果没有设置spring.profiles.active,Spring将会查找spring.profiles.default的值来激活profile;
  • 如果都没有设置,那就意味着没有激活的profile,因此上述代码中的Datasource bean都不会创建,只会创建没有定义在profile中的bean!

有多种方式来设置这2个属性:

  • 作为DispatcherServlet的初始化参数
  • 作为Web应用的上下文参数
  • 作为JNDI条目
  • 作为环境变量
  • 作为JVM的系统属性
  • 在集成测试类上,使用@ActiveProfiles注解设置
  • 等等。。

相关内容

热门资讯

探秘西沙群岛:梦幻海底世界与多... 西沙群岛犹如南海中的璀璨明珠,散发出迷人的光彩。那里有形态万千、色彩缤纷的珊瑚礁,它们在碧蓝的海水中...
陕西四天三夜三人旅游行程攻略,... 随着春天的深入,我带着家人踏上了一段期待已久的西安之旅。作为历史文化的爱好者,我一直梦想着能带着家人...
同福客栈“空降”大唐不夜城!沉... 华灯璀璨的大唐不夜城,一座复刻版“同福客栈”惊喜亮相!近日,果子熟了无糖茶携手国民经典IP《武林外传...
和姐妹去黄山旅游六天多少钱?安... 2025年的夏天,我和三个姐妹终于把攒了两年的年假凑到了一起。刷着朋友圈里黄山云海翻涌的照片,我们一...
惬意!藏在西安周边的宝藏村落 “小扇引微凉,悠悠夏日长”正值仲夏时节为大家推荐5处西安的宝藏村落让你的周末更加惬意!充满活力!一起...
北京4日游最佳行程推荐,北京四... 北京不仅有着雄伟壮观的皇家宫殿、历史悠久的文化古迹,还有着繁华的都市风貌和丰富的现代文化活动。从古老...
一家四口去黄山玩六天五晚人均花... 黄山,这座闻名遐迩的名山,一直是我心心念念的旅游目的地。今年夏天,我们一家四口终于踏上了前往黄山的旅...
广西玩四天大概要多少钱,桂林4... 宝子们,桂林,这座位于广西东北部的城市,宛如一颗镶嵌在大地上的璀璨明珠,散发着独特而迷人的魅力。它以...
暑假去陕西四天三夜行程,西安4... 西安,这座承载着十三朝兴衰的千年古都,宛如一颗璀璨的明珠,镶嵌在华夏大地的西北部。从威严壮观的兵马俑...
【辉煌60载 魅力新西藏】以时... play stop mute max volume repeat 七月的仲夏,青藏高原凉暖相宜...
陕西四天三夜旅游行程,游玩四天... 西安,这座承载着中华五千年文明史的古都,一直是我心驰神往的旅行目的地。古老的城墙、巍峨的宫殿、神秘的...
新疆9天8晚旅游路线,假期去乌... 宝子们,是不是一到假期就为去哪儿玩而发愁?又想玩得好,又不想花太多钱。今天我就来给大家分享一下我亲身...
暑假去北京4日游怎么玩,北京四... 北京不仅有着雄伟壮观的皇家宫殿、历史悠久的文化古迹,还有着繁华的都市风貌和丰富的现代文化活动。从古老...
陕西四天三夜游玩行程,4天3夜... 作为一个热爱历史与文化的旅行者,我一直对西安这座千年古都充满了向往。终于,在这个假期,我和伴侣决定踏...
带娃去北京4天3晚行程推荐,北... 北京,这座古老而现代交织的都市,总是以其独特的韵味吸引着无数游客。作为中国的首都,北京不仅承载着厚重...
北京4天3晚旅游路线,暑假去北... 北京,这座古老而又现代的城市,总是以其独特的魅力吸引着无数游客。它是中国的首都,承载着千年的历史与文...
北京玩4天怎么玩,北京玩四天人... 北京不仅有着雄伟壮观的皇家宫殿、历史悠久的文化古迹,还有着繁华的都市风貌和丰富的现代文化活动。从古老...
原创 南... 南宁一家4口的晚餐,在朋友圈火了,网友:比上馆子吃的还行! 作为上班族妈妈,每天一家人的晚餐不仅是...
扎根“泥土” 连接“云端” 7月17日,王静在韩城市板桥镇板桥村录制视频。记者 彭一鹏 摄 讲述人:韩城市公安局巡特警大队副大队...
大部分免费!郑州9个体育公园推... 郑州9大体育公园,看看哪一个离你家最近,一起运动起来吧!一、世纪体育公园公园简介:该场馆免费开放,设...