干掉祖傳代碼 之 spring的@Value注解


from:https://tuhrig.de/why-using-springs-value-annotation-is-bad/

為什么使用Spring的@Value注釋不好

@Value

配置是每個擁有數百行代碼的每個應用程序的重要主題。如果您使用的是Spring,通常會使用Spring的@Value注釋從Java屬性文件中加載值。可能看起來像這樣:

 

 

如果這樣做,Spring將從my.config.property.key 屬性文件中將鍵的值注入到您的類中,您就完成了。簡單!也許太容易了……

會發生什么…

當您在應用程序中使用此技術時會發生什么?好吧,只要需要一些屬性,就可以注入它。您將其注入服務,控制器和組件中,並將正確的屬性注入不同的類中。這很簡單,而且絕對是該機制的目的。

但是,這僅意味着分散整個應用程序的配置。每個類都可以選擇幾個要使用的屬性。您將不知道或無法控制哪個類正在使用哪些屬性。最后,您將對項目進行全文搜索,以查找使用單個鍵的位置。如果您想重命名這些鍵之一,或者需要為單元測試中的每個類的每個屬性設置每個屬性,您將獲得很多樂趣。

配置即服務

取而代之的是,配置也應該是應用程序的封裝服務,例如任何其他功能。您將持久性封裝在DAO中,將REST服務封裝在控制器中,並將安全性封裝在身份驗證器中。那么為什么不封裝配置呢?

如果這樣做,您將負有單一責任,可以加載並從中獲取配置。與任何其他服務一樣,您可以輕松更改實現。也許您不想從屬性文件中加載屬性,而是從數據庫或Web服務中加載!如果將配置封裝在服務中,那沒什么大不了的。您只需更改實現。您還可以為您的配置編寫一些單元測試(為什么不這樣做?當組合屬性或根據其他幾個屬性確定某個配置時,配置會變得很復雜!),也可以對配置服務中的屬性進行完整性檢查。您可以進行日志記錄,可以進行安全保護(也許密碼文件的路徑在所有地方都不應該看到,對不對?),可以進行緩存,可以進行……好吧,您就明白了。

 

 

甚至更好

如果您使用的是Spring Boot(不僅是Spring),則無需重新發明輪子。Spring Boot提供了一種優雅的方式來將配置與應用程序的其余部分分開:@ConfigurationProperties通過使用Spring Boot的@ConfigurationProperties,您可以輕松地將配置封裝在一個單獨的類中,並避免在整個代碼中分散對配置文件的直接依賴關系。在這里閱讀更多

from:https://tuhrig.de/using-configurationproperties-to-separate-service-and-configuration

使用@ConfigurationProperties分隔服務和配置

大約兩年前,我寫了一篇文章“為什么使用Spring的@Value注釋不好”。我描述了為什么@Value在整個代碼中都應避免使用注釋。通過@Value在服務,控制器和其他Spring組件中使用批注,您將在整個應用程序中分散配置。在最壞的情況下,您將在多個類中連接相同的值。如果您想在某天更改此值,則需要觸摸所有此類。

取而代之的是,配置應該像數據庫訪問或REST端點一樣是應用程序的封裝方面。我們希望將配置與實際服務,控制器和組件分開。

Spring Boot的方法

Spring Boot提供了一個名為的注釋@ConfigurationProperties正如您在這里可以讀到的,它是為分離和外部化配置而設計的。那就是我們想要的!

讓我們舉個例子,並假設我們要配置與外部REST服務(它也可以是數據庫或其他任何東西)的連接。我們需要一個配置,包括用戶名,密碼和URL。配置文件(application.properties)如下所示:

 

 

通過使用Spring Boot的@ConfigurationProperties注釋,我們首先將編寫一個Java類來表示此配置:

 

 

如您所見,屬性文件及其Java表示形式之間有着非常明顯的匹配。讓我們看看如何使用此類:

 

 

如您所見,我們將所有配置封裝在一個類中,該類注入了我們的服務。該服務不再知道配置來自何處。它只知道它可以從MySuperServiceConfig類中接收配置分離完成!

我們還能做什么?

我們不僅分離了配置,而且將其轉換為Java類!這意味着我們可以使用它進行編碼!這里有一些例子和想法:

應用默認值

我們僅可以為應該配置但不太可能配置的屬性應用默認值。假設我們有一個端口:

 

 

在大多數情況下,端口將是8080。僅在極少數情況下,我們才會在測試系統中使用另一個端口。在這種情況下,我們可以應用默認值:

 

 

工藝配置

讓我們假設以下配置:

 

 

由於某些原因,我們希望能夠自行配置每個屬性。但是,在服務中,我們需要一個URL :http://some.where.com:8080/api/v1我們可以在我們的配置類中做到這一點!

 

 

創建不同的實現

我們的配置剛剛成為Spring Bean。這也意味着,我們可以用它來完成所有常見的Spring事情!例如,創建不同的實現。

 

 

通過這樣做,我們最終得到了與“為什么使用Spring的@Value注釋不好”中描述的解決方案類似的解決方案配置成為我們隱藏在界面后面的服務。我們可以更改獲取配置的方式(從屬性文件,硬編碼或從雲中的配置服務器)以及映射和處理方式。我們的實際服務將僅包含業務邏輯,而不必處理配置問題。

最好的問候,
托馬斯

更多

from:https://www.baeldung.com/spring-value-defaults

將Spring @Value與默認值一起使用

1.概述

 

Spring的@Value注釋提供了一種方便的方法來將屬性值注入到組件中。在屬性可能不存在的情況下提供合理的默認值也很有用

這就是我們在本文中要重點關注的內容–如何為@Value Spring批注指定默認值有關@Value的更詳細的快速指南,請參見此處的文章

2.字符串默認值

 

讓我們看一下為String屬性設置默認值的基本語法

  @Value("${some.key:my default value}")
  private String stringWithDefaultValue;

如果some.key無法解析,則將stringW ithDefaultValue設置為默認值“ my default value”

同樣,我們可以將零長度的String設置為默認值:

  @Value("${some.key:})"
  private String stringWithBlankDefaultValue;

3.基元

 

要為基本類型(例如booleanint)設置默認值,我們使用文字值:

  @Value("${some.key:true}")
  private boolean booleanWithDefaultValue;
  @Value("${some.key:42}")
  private int intWithDefaultValue;

如果願意,我們可以使用原始包裝器,方法是將類型更改為BooleanInteger

4.數組

 

我們還可以將逗號分隔的值列表注入數組:

  @Value("${some.key:one,two,three}")
  private String[] stringArrayWithDefaults;
   
  @Value("${some.key:1,2,3}")
  private int[] intArrayWithDefaults;

在上面的第一個示例中,值“一個”,“兩個”和“三個”作為默認值注入到stringArrayWithDefaults中

在第二個示例中,值1、2和3作為默認值注入到intArrayWithDefaults中

5.使用SpEL

 

我們還可以使用Spring Expression Language(SpEL)指定表達式和默認值。

在下面的示例中,我們希望將some.system.key設置為系統屬性,如果未設置,則希望使用“我的默認系統屬性值”作為默認值:

  @Value("#{systemProperties['some.key'] ?: 'my default system property value'}")
  private String spelWithDefaultValue;

六,結論

 

在這篇快速的文章中,我們研究了如何為希望使用Spring的@Value注釋注入的屬性設置默認值

像往常一樣,本文中使用的所有代碼示例都可以在GitHub project中找到

from:https://stackoverflow.com/questions/11991194/can-i-set-null-as-the-default-value-for-a-value-in-spring

Can I set null as the default value for a @Value in Spring? 

You must set the nullValue of the PropertyPlaceholderConfigurer. For the example I'm using the string @null but you can also use the empty string as nullValue.

Now you can use the string @null to represent the null value

@Value("${stuff.value:@null}") private String value;

from:https://farenda.com/spring/spring-value-default-value/

Spring @Value default value

This tutorial presents how to set default values in Spring @Value annotation, using properties syntax and Spring Expression Language (SPEL).

Spring Config class with static PropertySourcesPlaceholderConfigurer bean that is needed to resolve properties syntax inside @Value:

@Configuration
public class Config {
     @Bean
     public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
         // Needed by Spring to resolve ${} inside @Value:
         return new PropertySourcesPlaceholderConfigurer();
     }
}

Now a bean with defaults that we can access inside @Value:

@Component ( "defaults" )
public class Defaults {
     public String getHostname() {
         return "default.host" ;
     }
}

Examples of setting default values using @Value:

@Component
public class SampleSpringComponent {
 
     @Value ( "${hostname : localhost}" )
     private String hostName;
 
     @Value ( "${target.dir : #{systemProperties['java.io.tmpdir']}}" )
     private String dir;
 
     @Value ( "${hostconfig.hostname : #{@defaults.hostname}}" )
     private String spelHostname;
 
     @Value ( "#{systemProperties['java.user.home'] ?: '/tmp/default'}" )
     private String spelDir;
}

Results:

Host name:  localhost
Directory:  /tmp
SPEL Host name:  default.host
SPEL Directory: /tmp/default

Summary of setting defaults:

  1. Property syntax use: ${expected : default}
  2. SPEL use: #{expected[‘value’] ?: default} (Elvis operator)
  3. SPEL expressions can be mixed with property syntax to access beans in context or use other complex expressions.

 from:https://stackoverflow.com/questions/31711308/spring-value-escape-colon-in-default-value

Spring @Value轉義冒號(:)為默認值

61
 

更新: 對於4.2或更高版本的Spring,不需要單引號。Spring將第一個冒號視為特殊字符,並將其余所有字符用作單個字符串值。

對於4.2或更高版本的春季,

@Value("${prop.url:http://myurl.com}") 

對於以前的版本,我相信單引號可以解決問題:

@Value("${prop.url:'http://myurl.com'}")

又見神碼!

toString 做緩存?!笑話。。

 

貌似找到優雅退出的鼻祖了。 

 





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM