springboot自定义yml文件,springboot读取自定义yml配置文件
目录
自定义加载yml,附源码解读解决方法源码解读如何引入多个阳明海运股份有限公司方法方案一:无前缀,使用@值注解方案二:有前缀,无需@值注解
自定义加载yml,附源码解读
昨天在对公司的微服务配置文件标准化的过程中,发现将原来的性能文件转为阳明海运股份有限公司文件之后,微服务组件中标记有@配置的配置类都不能正常工作了,究其原因,是由于@财产来源属性默认只用于标记并告诉板簧罩加载性能类型的文件
spring boot 2.0.0.RELEASE版的文档解释如下:
YAML的缺点
无法使用@财产来源批注加载YAML文件。因此,如果您需要以这种方式加载值,您需要使用一个属性文件。
这段话的意思是说:
24.6.4 YAML缺点
YAML文件不能用@财产来源注解来标记加载。因此,在需要加载值的场景,你需要使用属性文件。
解决方法
解决这个问题并不难,我们只需要自定义一个格式文件加载类,并在@财产来源注解的工厂属性中声明就可以1000斯卡拉。版实现代码如下,弹簧靴版本为版本:
1、自定义yaml文件资源加载类
导入组织。spring框架。靴子。环境。yamlpropertysourceloaderimport组织。spring框架。核心。环境。资产来源导入组织。spring框架。核心。io。支持。{ DefaultPropertySourceFactory,EncodedResource}/** * yaml资源加载类*/class YamlPropertyLoaderFactory扩展DefaultPropertySourceFactory { override def createPropertySource(name : String,resource : encoded resource):属性源[_]={ if(resource==null){ super。createPropertySource(名称,资源)}返回新的YamlPropertySourceLoader().load(resource.getResource。获取文件名,资源。获取资源,null) }}这个类继承自DefaultPropertySourceFactory类,并重写了createPropertySource方法。
2、引入@PropertySource注解并使用
导入com。核心。糖膏剂yamlpropertyloaderfactory导入javax。坚持。entitymanagerfactory导入javax。SQL。数据源导入组织。spring框架。豆子。工厂。注释。{自动连线,限定词}导入组织。spring框架。靴子。自动配置。JDBC。数据源构建器导入组织。spring框架。靴子。语境。属性。配置属性导入组织。spring框架。靴子。ORM。JPA。entitymanagerfactorybuilderimport组织。spring框架。语境。注释。{ 0
tory.config.EnableJpaRepositoriesimport org.springframework.orm.jpa.{JpaTransactionManager, LocalContainerEntityManagerFactoryBean}import org.springframework.transaction.PlatformTransactionManager/** * JPA 数据源配置 */@Configuration@PropertySource(value = Array("classpath:/bootstrap-report.yml"), factory = classOf[YamlPropertyLoaderFactory])@EnableJpaRepositories( entityManagerFactoryRef = "reportEntityManager", transactionManagerRef = "reportTransactionManager", basePackages = Array("com.report.dao"))class ReportDBConfig { @Autowired private var env: Environment = _ @Bean @ConfigurationProperties(prefix = "spring.datasource.report") def reportDataSource(): DataSource = DataSourceBuilder.create.build @Bean(name = Array("reportEntityManager")) def reportEntityManagerFactory(builder: EntityManagerFactoryBuilder): LocalContainerEntityManagerFactoryBean = { val entityManager = builder .dataSource(reportDataSource()) .packages("com.report.model") //设置JPA实体包路径 .persistenceUnit("reportPU") .build entityManager.setJpaProperties(additionalProperties()) entityManager } @Bean(name = Array("reportTransactionManager")) def reportTransactionManager(@Qualifier("reportEntityManager") entityManagerFactory: EntityManagerFactory): PlatformTransactionManager = { new JpaTransactionManager(entityManagerFactory) } /** * 获取JPA配置 * * @return */ def additionalProperties(): Properties = { val properties = new Properties(); properties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.report.hibernate.ddl-auto")) properties.setProperty("hibernate.show_sql", env.getProperty("spring.jpa.report.show-sql")) properties.setProperty("hibernate.dialect", env.getProperty("spring.jpa.report.database-platform")) properties }}
源码解读
实现该功能涉及两个地方:
1、@PropertySource注解:用于声明和配置自定义配置类需要加载的配置文件信息,源码及属性解释如下:
package org.springframework.context.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Repeatable;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.core.io.support.PropertySourceFactory;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Repeatable(PropertySources.class)public @interface PropertySource { // 用于声明属性源名称 String name() default ""; // 声明属性文件位置 String[] value(); // 是否忽略未找到的资源 boolean ignoreResourceNotFound() default false; // 声明配置文件的编码 String encoding() default ""; // 声明解析配置文件的类 Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;}
2、spring boot配置文件解析类:
在@PropertySource注解的定义中,属性factory主要用来声明解析配置文件的类,这个类必须是PropertySourceFactory接口的实现,在我们自定义了yaml文件加载类之后,它的实现关系如下:
从以上类图可以发现,它的实现类主要有2个:
DefaultPropertySourceFactory
:默认的配置文件解析类,主要用于解析properties配置文件YamlPropertyLoaderFactory
:自定义的yaml资源解析类,主要用于解析yaml配置文件,使用时需要在PropertySource注解的factory属性上声明这两个类将配置文件解析后,会将属性信息存入Spring的Environment对象中,以供我们通过@Value注解等方式使用。
因此,我们如果遇到spring boot不能加载并解析自定义配置的时候,可以试试自定义配置文件解析类解决。
参考链接
YAML Shortcomings
Exposing YAML as Properties in the Spring Environment
ConfigurationProperties loading list from YML:base on kotlin
Properties转YAML idea插件——生产力保证:Properties to YAML Converter
如何引入多个yml方法
SpringBoot默认加载的是application.yml文件,所以想要引入其他配置的yml文件,就要在application.yml中激活该文件
定义一个application-resources.yml文件(注意:必须以application-开头)
application.yml中:
spring: profiles: active: resources
以上操作,xml自定义文件加载完成,接下来进行注入。
application-resources.yml配置文件代码:
user: filepath: 12346 uname: "13"admin: aname: 26
方案一:无前缀,使用@Value注解
@Component//@ConfigurationProperties(prefix = "user")public class User { @Value("${user.filepath}") private String filepath; @Value("${user.uname}") private String uname; public String getFilepath() { return filepath; } public void setFilepath(String filepath) { this.filepath = filepath; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } @Override public String toString() { return "User{" + "filepath=" + filepath + + ", uname=" + uname + + }; }}
方案二:有前缀,无需@Value注解
@Component@ConfigurationProperties(prefix = "user")public class User { //@Value("${user.filepath}") private String filepath; //@Value("${user.uname}") private String uname; public String getFilepath() { return filepath; } public void setFilepath(String filepath) { this.filepath = filepath; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } @Override public String toString() { return "User{" + "filepath=" + filepath + + ", uname=" + uname + + }; }}
测试类:
package com.sun123.springboot;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)@SpringBootTestpublic class UTest { @Autowired User user; @Test public void test01(){ System.out.println(user); }}
测试结果:
以上为个人经验,希望能给大家一个参考,也希望大家多多支持盛行IT。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。