如何为 Spring Boot 应用程序的 gradle 构建设置活动配置文件?

Posted

技术标签:

【中文标题】如何为 Spring Boot 应用程序的 gradle 构建设置活动配置文件?【英文标题】:how to set active profile for gradle build of spring boot application? 【发布时间】:2017-01-25 05:59:12 【问题描述】:

这是我的 spring-boot 应用程序的 DbConfig。

@Configuration
@EnableTransactionManagement
public class DBConfig


    @Bean
    public LocalSessionFactoryBean sessionFactory()
    
        ....
    

    @Bean
    public DataSource aaDataSource()
    
     .....
    

public PlatformTransactionManager transactionManager()
    
        ....
    

    private Properties hibernateProperties()
    
       ....
    

这是我的测试课

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class ApplicationTests 

    @Test
    public void contextLoads() 
    

这是一个 gradle 项目。 当我在本地运行 gradlew clean build 时,我会成功构建,因为我在 application.properties 中的连接设置与我的 sql 连接匹配。

但是当我在我们的 qa 环境(数据库是 qa one)中从 jenkins box 运行时,构建失败并出现以下异常。

java.lang.IllegalStateException: Failed to load ApplicationContext
....
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is com.zaxxer.hikari.pool.PoolInitializationException: Exception during pool initialization
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(Abstract
.....
Caused by: com.zaxxer.hikari.pool.PoolInitializationException: Exception during pool initialization
    at com.zaxxer.hikari.pool.BaseHikariPool.initializeConnections(BaseHikariPool.java:544)
    at com.zaxxer.hikari.pool.BaseHikariPool.<init>(BaseHikariPool.java:171)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:60)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:48)
.....
Caused by: java.sql.SQLException: Access denied for user 'admin1'@'localhost' (using password: YES)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:998)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3835)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3771)

我尝试在具有 qa db 设置的 src/main/resources/ 中使用 application-qa.properties 运行 gradlew clean build -Dspring.profiles.active=qa。构建仍然失败,出现同样的异常。

我有两个选择。

    运行构建跳过数据源 bean 创建。我仍然需要运行我的单元测试,因为它们不依赖数据源

    或将正确的设置传递给 gradle build 以便创建应用程序上下文。

我更喜欢第二个选项来让它工作

【问题讨论】:

请检查您的 MySql 连接。在 pom.xml 中的 spring boot maven 插件中添加配置文件。在application.properties 文件spring.profile.active 中设置您的活动配置文件。为什么不运行测试目标,只运行测试类呢? 【参考方案1】:

如果您的要求是在外部进行控制(即,在启动 Gradle 时通过命令行),您可以修改 Gradle test 任务配置,如下所示。

test 
    systemProperty("spring.profiles.active", project.properties.get("springProfiles"))
    // ...

然后您可以像这样为springProfiles 设置一个值:gradlew clean build -PspringProfiles=ci(其中ci 是您希望在 CI 服务器上激活的配置文件的名称)。

以上内容将使spring.profiles.active 可用作您的测试的JVM 系统属性;但是,您仍然需要为 Spring TestContext Framework 设置活动配置文件。

为此,您需要使用@ActiveProfiles 注释您的测试类,但您需要实现自定义ActiveProfilesResolver 并通过@ActiveProfiles(resolver = MyCustomResolver.class) 注册,而不是传递静态配置文件。然后,您的客户解析器可以读取并返回 spring.profiles.active 系统属性的值。

另一种选择是实现自定义ApplicationContextInitializer,以编程方式设置活动配置文件(类似于自定义ActiveProfilesResolver)。您可以通过@SpringApplicationConfiguration(initializers = MyCustomInitializer.class) 配置其中之一。

还有一个选项是programmatically set the active profiles directly in your SpringApplication——例如,基于系统属性或环境变量。

所以,你有几个选择。

【讨论】:

这似乎有效。但不确定这是否是正确的方式SPRING_CONFIG_LOCATION=/var/config/application-qa.properties gradle clean build

以上是关于如何为 Spring Boot 应用程序的 gradle 构建设置活动配置文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何为具有 Spring Security 配置的 Spring Boot API 编写单元测试

如何为我的 Spring Boot webapp 选择 URL?

如何为我的 Spring Boot 控制器执行单元测试?

如何为 Spring Boot 应用程序设置自定义 Http 标头“服务器”

如何为 Spring Boot 应用程序配置嵌入式 Tomcat 虚拟主机?

如何为 Spring Boot 应用程序外部化 data.sql