最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot自定義加載yml實(shí)現(xiàn)方式,附源碼解讀

 更新時(shí)間:2022年03月24日 09:47:55   作者:九州暮云  
這篇文章主要介紹了SpringBoot自定義加載yml實(shí)現(xiàn)方式附源碼解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

自定義加載yml,附源碼解讀

昨天在對(duì)公司的微服務(wù)配置文件標(biāo)準(zhǔn)化的過(guò)程中,發(fā)現(xiàn)將原來(lái)的properties文件轉(zhuǎn)為yml文件之后,微服務(wù)module中標(biāo)記有@Configuration的配置類都不能正常工作了,究其原因,是由于@PropertySource屬性默認(rèn)只用于標(biāo)記并告訴spring boot加載properties類型的文件

spring boot 2.0.0.RELEASE版的文檔解釋如下:

24.6.4 YAML Shortcomings

YAML files cannot be loaded by using the @PropertySource annotation. So, in the case that you need to load values that way, you need to use a properties file.

這段話的意思是說(shuō):

24.6.4 YAML 缺點(diǎn)

YAML 文件不能用 @PropertySource 注解來(lái)標(biāo)記加載。因此,在需要加載值的場(chǎng)景,你需要使用屬性文件。

解決方法

解決這個(gè)問(wèn)題并不難,我們只需要自定義一個(gè)yaml文件加載類,并在@PropertySource注解的factory屬性中聲明就可以。scala版實(shí)現(xiàn)代碼如下,spring boot版本為2.0.0.RELEASE:

1、自定義yaml文件資源加載類 

import org.springframework.boot.env.YamlPropertySourceLoader
import org.springframework.core.env.PropertySource
import org.springframework.core.io.support.{DefaultPropertySourceFactory, EncodedResource}
/**
? * yaml資源加載類
? */
class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory{
? override def createPropertySource(name: String, resource: EncodedResource): PropertySource[_] = {
? ? if (resource == null) {
? ? ? super.createPropertySource(name, resource)
? ? }
? ? return new YamlPropertySourceLoader().load(resource.getResource.getFilename, resource.getResource, null)
? }
}

這個(gè)類繼承自DefaultPropertySourceFactory類,并重寫了createPropertySource方法。

2、引入@PropertySource注解并使用

import com.core.conf.YamlPropertyLoaderFactory
import javax.persistence.EntityManagerFactory
import javax.sql.DataSource
import org.springframework.beans.factory.annotation.{Autowired, Qualifier}
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder
import org.springframework.context.annotation.{Bean, Configuration, PropertySource}
import org.springframework.core.env.Environment
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.orm.jpa.{JpaTransactionManager, LocalContainerEntityManagerFactoryBean}
import org.springframework.transaction.PlatformTransactionManager
/**
? * JPA 數(shù)據(jù)源配置
? */
@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") //設(shè)置JPA實(shí)體包路徑
? ? ? .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
? }
}

源碼解讀

實(shí)現(xiàn)該功能涉及兩個(gè)地方:

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主要用來(lái)聲明解析配置文件的類,這個(gè)類必須是PropertySourceFactory接口的實(shí)現(xiàn),在我們自定義了yaml文件加載類之后,它的實(shí)現(xiàn)關(guān)系如下:

從以上類圖可以發(fā)現(xiàn),它的實(shí)現(xiàn)類主要有2個(gè):

  • DefaultPropertySourceFactory:默認(rèn)的配置文件解析類,主要用于解析properties配置文件
  • YamlPropertyLoaderFactory:自定義的yaml資源解析類,主要用于解析yaml配置文件,使用時(shí)需要在PropertySource注解的factory屬性上聲明

這兩個(gè)類將配置文件解析后,會(huì)將屬性信息存入Spring的Environment對(duì)象中,以供我們通過(guò)@Value注解等方式使用。

因此,我們?nèi)绻龅絪pring boot不能加載并解析自定義配置的時(shí)候,可以試試自定義配置文件解析類解決。

參考鏈接

YAML Shortcomings

Exposing YAML as Properties in the Spring Environment

ConfigurationProperties loading list from YML:base on kotlin

Properties轉(zhuǎn)YAML idea插件——生產(chǎn)力保證:Properties to YAML Converter

如何引入多個(gè)yml方法

SpringBoot默認(rèn)加載的是application.yml文件,所以想要引入其他配置的yml文件,就要在application.yml中激活該文件

定義一個(gè)application-resources.yml文件(注意:必須以application-開(kāi)頭)

application.yml中:

spring:?
?profiles:
? ?active: resources

以上操作,xml自定義文件加載完成,接下來(lái)進(jìn)行注入。

application-resources.yml配置文件代碼:

user:
?filepath: 12346
?uname: "13"
admin:
?aname: 26

方案一:無(wú)前綴,使用@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 + '\'' +
? ? ? ? ? ? ? ?'}';
? ?}
}

方案二:有前綴,無(wú)需@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 + '\'' +
? ? ? ? ? ? ? ?'}';
? ?}
}

測(cè)試類:

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)
@SpringBootTest
public class UTest {
? ?@Autowired
? ?User user;
? ?@Test
? ?public void test01(){
? ? ? ?System.out.println(user);
? ?}
}

測(cè)試結(jié)果:

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java實(shí)現(xiàn)/創(chuàng)建線程的幾種方式小結(jié)

    java實(shí)現(xiàn)/創(chuàng)建線程的幾種方式小結(jié)

    在JAVA中,用Thread類代表線程,所有線程對(duì)象都必須是Thread類或者Thread類子類的實(shí)例,下面這篇文章主要介紹了java實(shí)現(xiàn)/創(chuàng)建線程的幾種方式,需要的朋友可以參考下
    2021-08-08
  • Java程序去調(diào)用并執(zhí)行shell腳本及問(wèn)題總結(jié)(推薦)

    Java程序去調(diào)用并執(zhí)行shell腳本及問(wèn)題總結(jié)(推薦)

    這篇文章主要介紹了Java程序去調(diào)用并執(zhí)行shell腳本及問(wèn)題總結(jié),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • java poi判斷excel是xlsx還是xls類型

    java poi判斷excel是xlsx還是xls類型

    這篇文章主要為大家詳細(xì)介紹了如何利用java poi來(lái)判斷excel是xlsx還是xls類型,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考一下
    2024-10-10
  • Java中字符串String的+和+=及循環(huán)操作String原理詳解

    Java中字符串String的+和+=及循環(huán)操作String原理詳解

    Java編譯器在編譯時(shí)對(duì)String的+和+=操作會(huì)創(chuàng)建StringBuilder對(duì)象來(lái)進(jìn)行字符串的拼接,下面這篇文章主要給大家介紹了關(guān)于Java中字符串String的+和+=及循環(huán)操作String原理的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • Java生成日期時(shí)間存入Mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法

    Java生成日期時(shí)間存入Mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法

    本文主要介紹了Java生成日期時(shí)間存入Mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Java8接口之默認(rèn)方法與靜態(tài)方法詳解

    Java8接口之默認(rèn)方法與靜態(tài)方法詳解

    java8中為接口新增了一項(xiàng)功能,定義一個(gè)或者更多個(gè)靜態(tài)方法,類似于類中的靜態(tài)方法,接口定義的靜態(tài)方法可以獨(dú)立于任何對(duì)象調(diào)用,下面這篇文章主要給大家介紹了關(guān)于Java8接口之默認(rèn)方法與靜態(tài)方法的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • Struts2攔截器Interceptor的原理與配置實(shí)例詳解

    Struts2攔截器Interceptor的原理與配置實(shí)例詳解

    攔截器是一種AOP(面向切面編程)思想的編程方式.它提供一種機(jī)制是開(kāi)發(fā)者能夠把相對(duì)獨(dú)立的代碼抽離出來(lái),配置到Action前后執(zhí)行。下面這篇文章主要給大家介紹了關(guān)于Struts2攔截器Interceptor的原理與配置的相關(guān)資料,需要的朋友可以參考下。
    2017-11-11
  • Java中的Phaser使用詳解

    Java中的Phaser使用詳解

    這篇文章主要介紹了Java中的Phaser使用詳解,與其他障礙不同,注冊(cè)在phaser上進(jìn)行同步的parties數(shù)量可能會(huì)隨時(shí)間變化,任務(wù)可以隨時(shí)進(jìn)行注冊(cè),需要的朋友可以參考下
    2023-11-11
  • springMvc注解之@ResponseBody和@RequestBody詳解

    springMvc注解之@ResponseBody和@RequestBody詳解

    本篇文章主要介紹了springMvc注解之@ResponseBody和@RequestBody詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • 基于SpringBoot和Dify實(shí)現(xiàn)流式響應(yīng)輸出

    基于SpringBoot和Dify實(shí)現(xiàn)流式響應(yīng)輸出

    這篇文章主要為大家詳細(xì)介紹了如何基于SpringBoot和Dify實(shí)現(xiàn)流式響應(yīng)輸出效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下
    2025-03-03

最新評(píng)論

河间市| 文登市| 兴隆县| 通河县| 比如县| 义马市| 金塔县| 高州市| 宁津县| 鄂州市| 社会| 宜兴市| 瑞金市| 怀化市| 香格里拉县| 桐梓县| 宜兰县| 九龙县| 镇安县| 岳西县| 出国| 巨鹿县| 潮州市| 富蕴县| 伊宁市| 前郭尔| 玉山县| 江都市| 石狮市| 平谷区| 乐东| 永修县| 印江| 高唐县| 南漳县| 西安市| 柳河县| 岐山县| 资源县| 西昌市| 寿阳县|