自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一起來看看@Value竟然能玩出這么多花樣

開發(fā) 前端
今天咱們重點聊聊@Value注解,因為它是一個非常有用,但極其容易被忽視的注解,絕大多數(shù)人可能只用過它的一部分功能,這是一件非常遺憾的事情。

[[427987]]

前言

對于從事java開發(fā)工作的小伙伴來說,spring框架肯定再熟悉不過了。spring給開發(fā)者提供了非常豐富的api,滿足我們?nèi)粘5墓ぷ餍枨蟆?/p>

如果想要創(chuàng)建bean實例,可以使用@Controller、@Service、@Repository、@Component等注解。

如果想要依賴注入某個對象,可以使用@Autowired和@Resource注解。

如果想要開啟事務(wù),可以使用@Transactional注解。

如果想要動態(tài)讀取配置文件中的某個系統(tǒng)屬性,可以使用@Value注解。

等等,還有很多。。。

前面幾種常用的注解,在我以往的文章《@Autowired的這些騷操作,你都知道嗎?》《聊聊spring事務(wù)失效的12種場景,太坑了》《驚呆了,spring中竟然有12種定義bean的方法》中已經(jīng)介紹過了,在這里就不過多講解了。

今天咱們重點聊聊@Value注解,因為它是一個非常有用,但極其容易被忽視的注解,絕大多數(shù)人可能只用過它的一部分功能,這是一件非常遺憾的事情。

所以今天有必要和大家一起,重新認(rèn)識一下@Value。

1. 由一個例子開始

假如在UserService類中,需要注入系統(tǒng)屬性到userName變量中。通常情況下,我們會寫出如下的代碼:

  1. @Service 
  2. public class UserService { 
  3.  
  4.     @Value("${susan.test.userName}"
  5.     private String userName; 
  6.  
  7.     public String test() { 
  8.         System.out.println(userName); 
  9.         return userName; 
  10.     } 

通過@Value注解指定系統(tǒng)屬性的名稱susan.test.userName,該名稱需要使用${}包起來。

這樣spring就會自動的幫我們把對應(yīng)的系統(tǒng)屬性值,注入到userName變量中。

不過,上面功能的重點是要在applicationContext.properties文件(簡稱:配置文件)中配置同名的系統(tǒng)屬性:

  1. #張三 
  2. susan.test.userName=\u5f20\u4e09 

那么,名稱真的必須完全相同嗎?

2. 關(guān)于屬性名

這時候,有些朋友可能會說:在@ConfigurationProperties配置類中,定義的參數(shù)名可以跟配置文件中的系統(tǒng)屬性名不同。

比如,在配置類MyConfig類中定義的參數(shù)名是userName:

  1. @Configuration 
  2. @ConfigurationProperties(prefix = "susan.test"
  3. @Data 
  4. public class MyConfig { 
  5.     private String userName; 

而配置文件中配置的系統(tǒng)屬性名是:

  1. susan.test.user-name=\u5f20\u4e09 

類中用的userName,而配置文件中用的user-name,不一樣。但測試之后,發(fā)現(xiàn)該功能能夠正常運行。

配置文件中的系統(tǒng)屬性名用 駝峰標(biāo)識 或 小寫字母加中劃線的組合,spring都能找到配置類中的屬性名userName進行賦值。

由此可見,配置文件中的系統(tǒng)屬性名,可以跟配置類中的屬性名不一樣。不過,有個前提,前綴susan.test必須相同。

那么,@Value注解中定義的系統(tǒng)屬性名也可以不一樣嗎?

答案:不能。如果不一樣,啟動項目時會直接報錯。

此外,如果只在@Value注解中指定了系統(tǒng)屬性名,但實際在配置文件中沒有配置它,也會報跟上面一樣的錯。

所以,@Value注解中指定的系統(tǒng)屬性名,必須跟配置文件中的相同。

3. 亂碼問題

不知道細心的小伙伴們有沒有發(fā)現(xiàn),我配置的屬性值:張三,其實是轉(zhuǎn)義過的。

  1. susan.test.userName=\u5f20\u4e09 

為什么要做這個轉(zhuǎn)義?

假如在配置文件中配置中文的張三:

  1. susan.test.userName=張三 

最后獲取數(shù)據(jù)時,你會發(fā)現(xiàn)userName竟然出現(xiàn)了亂碼:

  • å¼ ä¸‰

what?

為什么會出現(xiàn)亂碼?

答:在springboot的CharacterReader類中,默認(rèn)的編碼格式是ISO-8859-1,該類負責(zé).properties文件中系統(tǒng)屬性的讀取。如果系統(tǒng)屬性包含中文字符,就會出現(xiàn)亂碼。

那么,如何解決亂碼問題呢?

目前主要有如下三種方案:

  1. 手動將ISO-8859-1格式的屬性值,轉(zhuǎn)換成UTF-8格式。
  2. 設(shè)置encoding參數(shù),不過這個只對@PropertySource注解有用。
  3. 將中文字符用unicode編碼轉(zhuǎn)義。

顯然@Value不支持encoding參數(shù),所以方案2不行。

假如使用方案1,具體實現(xiàn)代碼如下:

  1. @Service 
  2. public class UserService { 
  3.  
  4.     @Value(value = "${susan.test.userName}"
  5.     private String userName; 
  6.  
  7.     public String test() { 
  8.         String userName1 = new String(userName.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); 
  9.         System.out.println(); 
  10.         return userName1; 
  11.     } 

確實可以解決亂碼問題。

但如果項目中包含大量中文系統(tǒng)屬性值,每次都需要加這樣一段特殊轉(zhuǎn)換代碼。出現(xiàn)大量重復(fù)代碼,有沒有覺得有點惡心?

反轉(zhuǎn)我被惡心到了。

那么,如何解決代碼重復(fù)問題呢?

答:將屬性值的中文內(nèi)容轉(zhuǎn)換成unicode。

類似于這樣的:

  1. susan.test.userName=\u5f20\u4e09 

這種方式同樣能解決亂碼問題,不會出現(xiàn)惡心的重復(fù)代碼。但需要做一點額外的轉(zhuǎn)換工作,不過這個轉(zhuǎn)換非常容易,因為有現(xiàn)成的在線轉(zhuǎn)換工具。

推薦使用這個工具轉(zhuǎn)換:http://www.jsons.cn/unicode/

在這里順便告訴你一個小秘密:如果你使用的是.yml或.yaml格式的配置文件,并不會出現(xiàn)中文亂碼問題。

這又是為什么?

因為.yml或.yaml格式的配置文件,最終會使用UnicodeReader類進行解析,它的init方法中,首先讀取BOM文件頭信息,如果頭信息中有UTF8、UTF16BE、UTF16LE,就采用對應(yīng)的編碼,如果沒有,則采用默認(rèn)UTF8編碼。

需要注意的是:亂碼問題一般出現(xiàn)在本地環(huán)境,因為本地直接讀取的.properties配置文件。在dev、test、生產(chǎn)等環(huán)境,如果從zookeeper、apollo、nacos等配置中心中獲取系統(tǒng)參數(shù)值,走的是另外的邏輯,并不會出現(xiàn)亂碼問題。

4.默認(rèn)值

有時候,默認(rèn)值是我們非常頭疼的問題。

為什么這樣說呢?

因為很多時候使用java的默認(rèn)值,并不能滿足我們的日常工作需求。

比如有這樣一個需求:如果配置了系統(tǒng)屬性,userName就用配置的屬性值。如果沒有配置,則userName用默認(rèn)值susan。

有些朋友可能認(rèn)為可以這樣做:

  1. @Value(value = "${susan.test.userName}"
  2. private String userName = "susan"

在定義參數(shù)時直接給個默認(rèn)值,但如果仔細想想這招是行不通的的。因為設(shè)置userName默認(rèn)值的時機,比@Value注解依賴注入屬性值要早,也就是說userName初始化好了默認(rèn)值,后面還是會被覆蓋。

那么,到底該如何設(shè)置默認(rèn)值呢?

答:使用:。

例如:

  1. @Value(value = "${susan.test.userName:susan}"
  2. private String userName; 

在需要設(shè)置默認(rèn)值的系統(tǒng)屬性名后,加:符號。緊接著,在:右邊設(shè)置默認(rèn)值。

建議大家平時在使用@Value時,盡量都設(shè)置一個默認(rèn)值。如果不需要默認(rèn)值,寧可設(shè)置一個空。比如:

  1. @Value(value = "${susan.test.userName:}"
  2. private String userName; 

為什么這么說?

假如有這種場景:在business層中包含了UserService類,business層被api服務(wù)和job服務(wù)都引用了。但UserService類中@Value的userName只在api服務(wù)中有用,在job服務(wù)中根本用不到該屬性。

對于job服務(wù)來說,如果不在.properties文件中配置同名的系統(tǒng)屬性,則服務(wù)啟動時就會報錯。

這個坑,我之前踩過多次。所以,建議大家,使用@Value注解時,最好給參數(shù)設(shè)置一個默認(rèn)值,以防止出現(xiàn)類似的問題。

5. static變量

前面我們已經(jīng)見識過,如何使用@Value注解,給類的成員變量注入系統(tǒng)屬性值。

那么,問題來了,靜態(tài)變量可以自動注入系統(tǒng)屬性值不?

我們一起看看,假如將上面的userName定義成static的:

  1. @Value("${susan.test.userName}"
  2. private static String userName; 

程序可以正常啟動,但是獲取到userName的值卻是null。

由此可見,被static修飾的變量通過@Value會注入失敗。

作為好奇寶寶的你,此時肯定想問:如何才能給靜態(tài)變量注入系統(tǒng)屬性值呢?

答:這就需要使用如下的騷代碼了:

  1. @Service 
  2. public class UserService { 
  3.  
  4.     private static String userName; 
  5.  
  6.     @Value("${susan.test.userName}"
  7.     public void setUserName(String userName) { 
  8.         UserService.userName = userName; 
  9.     } 
  10.  
  11.     public String test() { 
  12.         return userName; 
  13.     } 

提供一個靜態(tài)參數(shù)的setter方法,在該方法上使用@Value注入屬性值,并且同時在該方法中給靜態(tài)變量賦值。

有些細心的朋友可能會發(fā)現(xiàn),@Value注解在這里竟然使用在setUserName方法上了,也就是對應(yīng)的setter方法,而不是在變量上。

有趣,有趣,這種用法有點高端喔。

不過,通常情況下,我們一般會在pojo實體類上,使用lombok的@Data、@Setter、@Getter等注解,在編譯時動態(tài)增加setter或getter方法,所以@Value用在方法上的場景其實不多。

6.變量類型

上面的內(nèi)容,都是用的字符串類型的變量進行舉例的。其實,@Value注解還支持其他多種類型的系統(tǒng)屬性值的注入。

6.1 基本類型

眾所周知,在Java中的基本數(shù)據(jù)類型有4類8種,然我們一起回顧一下:

  • 整型:byte、short、int、long
  • 浮點型:float、double
  • 布爾型:boolean
  • 字符型:char

相對應(yīng)地提供了8種包裝類:

  • 整型:Byte、Short、Integer、Long
  • 浮點型:Float、Double
  • 布爾型:Boolean
  • 字符型:Character

@Value注解對這8中基本類型和相應(yīng)的包裝類,有非常良好的支持,例如:

  1. @Value("${susan.test.a:1}"
  2. private byte a; 
  3.  
  4. @Value("${susan.test.b:100}"
  5. private short b; 
  6.  
  7. @Value("${susan.test.c:3000}"
  8. private int c; 
  9.  
  10. @Value("${susan.test.d:4000000}"
  11. private long d; 
  12.  
  13. @Value("${susan.test.e:5.2}"
  14. private float e; 
  15.  
  16. @Value("${susan.test.f:6.1}"
  17. private double f; 
  18.  
  19. @Value("${susan.test.g:false}"
  20. private boolean g; 
  21.  
  22. @Value("${susan.test.h:h}"
  23. private char h; 
  24.  
  25. @Value("${susan.test.a:1}"
  26. private byte a1; 
  27.  
  28. @Value("${susan.test.b:100}"
  29. private Short b1; 
  30.  
  31. @Value("${susan.test.c:3000}"
  32. private Integer c1; 
  33.  
  34. @Value("${susan.test.d:4000000}"
  35. private Long d1; 
  36.  
  37. @Value("${susan.test.e:5.2}"
  38. private Float e1; 
  39.  
  40. @Value("${susan.test.f:6.1}"
  41. private Double f1; 
  42.  
  43. @Value("${susan.test.g:false}"
  44. private Boolean g1; 
  45.  
  46. @Value("${susan.test.h:h}"
  47. private Character h1; 

有了這些常用的數(shù)據(jù)類型,我們在定義變量類型時,可以非常愉快的玩耍了,不用做額外的轉(zhuǎn)換。

6.2 數(shù)組

但只用上面的基本類型是不夠的,特別是很多需要批量處理數(shù)據(jù)的場景中。這時候可以使用數(shù)組,它在日常開發(fā)中使用的頻率很高。

我們在定義數(shù)組時可以這樣寫:

  1. @Value("${susan.test.array:1,2,3,4,5}"
  2. private int[] array; 

spring默認(rèn)使用逗號分隔參數(shù)值。

如果用空格分隔,例如:

  1. @Value("${susan.test.array:1 2 3 4 5}"
  2. private int[] array; 

spring會自動把空格去掉,導(dǎo)致數(shù)據(jù)中只有一個值:12345,注意千萬別搞錯了。

順便說一下,定義數(shù)組的時候,里面還是有挺多門道的。比如上面列子中,我的數(shù)據(jù)是:1,2,3,4,5。

如果我們把數(shù)組定義成:short、int、long、char、string類型,spring是可以正常注入屬性值的。

但如果把數(shù)組定義成:float、double類型,啟動項目時就會直接報錯。

小伙伴們,下巴驚掉了沒?

按理說,1,2,3,4,5用float、double是能夠表示的呀,為什么會報錯?

如果使用int的包裝類,比如:

  1. @Value("${susan.test.array:1,2,3,4,5}"
  2. private Integer[] array; 

啟動項目時同樣會報上面的異常。

此外,定義數(shù)組時一定要注意屬性值的類型,必須完全一致才可以,如果出現(xiàn)下面這種情況:

  1. @Value("${susan.test.array:1.0,abc,3,4,5}"
  2. private int[] array; 

屬性值中包含了1.0和abc,顯然都無法將該字符串轉(zhuǎn)換成int。

6.3 集合類

有了基本類型和數(shù)組,的確讓我們更加方便了。但對數(shù)據(jù)的處理,只用數(shù)組這一種數(shù)據(jù)結(jié)構(gòu)是遠遠不夠的,下面給大家介紹一下其他的常用數(shù)據(jù)結(jié)構(gòu)。

6.3.1 List

List是數(shù)組的變種,它的長度是可變的,而數(shù)組的長度是固定的。

我們看看List是如何注入屬性值的:

  1. @Value("${susan.test.list}"
  2. private List<String> list; 

最關(guān)鍵的是看配置文件:

  1. susan.test.list[0]=10 
  2. susan.test.list[1]=11 
  3. susan.test.list[2]=12 
  4. susan.test.list[3]=13 

當(dāng)你滿懷希望的啟動項目,準(zhǔn)備使用這個功能的時候,卻發(fā)現(xiàn)竟然報錯了。 

what?

看來@Value不支持這種直接的List注入。

那么,如何解決這個問題呢?

有人說用@ConfigurationProperties。

需要定義一個MyConfig類:

  1. @Configuration 
  2. @ConfigurationProperties(prefix = "susan.test"
  3. @Data 
  4. public class MyConfig { 
  5.     private List<String> list; 

然后在調(diào)用的地方這樣寫:

  1. @Service 
  2. public class UserService { 
  3.  
  4.     @Autowired 
  5.     private MyConfig myConfig; 
  6.  
  7.     public String test() { 
  8.         System.out.println(myConfig.getList()); 
  9.         return null
  10.     } 

這種方法確實能夠完成List注入。但是,只能說明@ConfigurationProperties注解的強大,跟@Value有半毛錢的關(guān)系?

答:沒有。

那么,問題來了,用@Value如何實現(xiàn)這個功能呢?

答:使用spring的EL表達式。

List的定義改成:

  1. @Value("#{'${susan.test.list}'.split(',')}"
  2. private List<String> list; 

使用#號加大括號的EL表達式。

然后配置文件改成:

  1. susan.test.list=10,11,12,13 

跟定義數(shù)組時的配置文件一樣。

6.3.2 Set

Set也是一種保存數(shù)據(jù)的集合,它比較特殊,里面保存的數(shù)據(jù)不會重復(fù)。

我們可以這樣定義Set:

  1. @Value("#{'${susan.test.set}'.split(',')}"
  2. private Set<String> set

配置文件是這樣的:

  1. susan.test.set=10,11,12,13 

Set跟List的用法極為相似。

但為了證明本節(jié)的獨特之處,我打算說點新鮮的內(nèi)容。

如何給List或者Set設(shè)置默認(rèn)值空呢?

有些朋友可能會說:這還不簡單,直接在@Value的$表達式后面加個:號不就行了。

具體代碼如下:

  1. @Value("#{'${susan.test.set:}'.split(',')}"
  2. private Set<String> set

結(jié)果卻跟想象中不太一樣:

Set集合怎么不是空的,而是包含了一個空字符串的集合?

好吧,那我在:號后加null,總可以了吧?

Set集合也不是空的,而是包含了一個"null"字符串的集合。

這也不行,那也不行,該如何是好?

答:使用EL表達式的empty方法。

具體代碼如下:

  1. @Value("#{'${susan.test.set:}'.empty ? null : '${susan.test.set:}'.split(',')}"
  2. private Set<String> set

運行之后,結(jié)果對了:

其實List也有類似的問題,也能使用該方法解決問題。

在這里溫馨的提醒一下,該判斷的表達式比較復(fù)雜,自己手寫非常容易寫錯,建議復(fù)制粘貼之后根據(jù)實際需求改改。

6.3.3 Map

還有一種比較常用的集合是map,它支持key/value鍵值對的形式保存數(shù)據(jù),并且不會出現(xiàn)相同key的數(shù)據(jù)。

我們可以這樣定義Map:

  1. @Value("#{${susan.test.map}}"
  2. private Map<String, String> map; 

配置文件是這樣的:

  1. susan.test.map={"name":"蘇三""age":"18"

這種用法跟上面稍微有一點區(qū)別。

設(shè)置默認(rèn)值的代碼如下:

  1. @Value("#{'${susan.test.map:}'.empty ? null : '${susan.test.map:}'}"
  2. private Map<String, String> map; 

7 EL高端玩法

前面我們已經(jīng)見識過spring EL表達式的用法了,在設(shè)置空的默認(rèn)值時特別有用。

其實,empty方法只是它很普通的用法,還有更高端的用法,不信我們一起看看。

7.1 注入bean

以前我們注入bean,一般都是用的@Autowired或者@Resource注解。例如:

  1. @Service 
  2. public class RoleService { 
  3.     public String getRoleName() { 
  4.         return "管理員"
  5.     } 
  6.  
  7. @Service 
  8. public class UserService { 
  9.  
  10.     @Autowired 
  11.     private RoleService roleService; 
  12.  
  13.     public String test() { 
  14.         System.out.println(roleService.getRoleName()); 
  15.         return null
  16.     } 

但我要告訴你的是@Value注解也可以注入bean,它是這么做的:

  1. @Value("#{roleService}"
  2. private RoleService roleService; 

通過這種方式,可以注入id為roleService的bean。

7.2 bean的變量和方法

通過EL表達式,@Value注解已經(jīng)可以注入bean了。既然能夠拿到bean實例,接下來,可以再進一步。

在RoleService類中定義了:成員變量、常量、方法、靜態(tài)方法。

  1. @Service 
  2. public class RoleService { 
  3.     public static final int DEFAULT_AGE = 18; 
  4.     public int id = 1000; 
  5.  
  6.     public String getRoleName() { 
  7.         return "管理員"
  8.     } 
  9.  
  10.     public static int getParentId() { 
  11.         return 2000; 
  12.     } 

在調(diào)用的地方這樣寫:

  1. @Service 
  2. public class UserService { 
  3.  
  4.     @Value("#{roleService.DEFAULT_AGE}"
  5.     private int myAge; 
  6.  
  7.     @Value("#{roleService.id}"
  8.     private int id; 
  9.  
  10.     @Value("#{roleService.getRoleName()}"
  11.     private String myRoleName; 
  12.  
  13.     @Value("#{roleService.getParentId()}"
  14.     private String myParentId; 
  15.  
  16.     public String test() { 
  17.         System.out.println(myAge); 
  18.         System.out.println(id); 
  19.         System.out.println(myRoleName); 
  20.         System.out.println(myParentId); 
  21.         return null
  22.     } 

在UserService類中通過@Value可以注入:成員變量、常量、方法、靜態(tài)方法獲取到的值,到相應(yīng)的成員變量中。

一下子有沒有豁然開朗的感覺,有了這些,我們可以通過@Value注解,實現(xiàn)更多的功能了,不僅僅限于注入系統(tǒng)屬性。

7.3 靜態(tài)類

前面的內(nèi)容都是基于bean的,但有時我們需要調(diào)用靜態(tài)類,比如:Math、xxxUtil等靜態(tài)工具類的方法,該怎么辦呢?

答:用T加括號。

示例1:

  1. @Value("#{T(java.io.File).separator}"
  2. private String path; 

可以注入系統(tǒng)的路徑分隔符到path中。

示例2:

  1. @Value("#{T(java.lang.Math).random()}"
  2. private double randomValue; 

可以注入一個隨機數(shù)到randomValue中。

7.4 邏輯運算

通過上面介紹的內(nèi)容,我們可以獲取到絕大多數(shù)類的變量和方法的值了。但有了這些值,還不夠,我們能不能在EL表達式中加點邏輯?

拼接字符串:

  1. @Value("#{roleService.roleName + '' + roleService.DEFAULT_AGE}"
  2. private String value; 

邏輯判斷:

  1. @Value("#{roleService.DEFAULT_AGE > 16 and roleService.roleName.equals('蘇三')}"
  2. private String operation; 

三目運算:

  1. @Value("#{roleService.DEFAULT_AGE > 16 ? roleService.roleName: '蘇三' }"
  2. private String realRoleName; 

還有很多很多功能,我就不一一列舉了。

EL表達式實在太強大了,對這方面如果感興趣的小伙伴可以找我私聊。

8 ${}和#{}的區(qū)別

上面巴拉巴拉說了這么多@Value的牛逼用法,歸根揭底就是${}和#{}的用法。

下面重點說說${}和#{}的區(qū)別,這可能是很多小伙伴比較關(guān)心的話題。

8.1 ${}

主要用于獲取配置文件中的系統(tǒng)屬性值。

例如:

  1. @Value(value = "${susan.test.userName:susan}"
  2. private String userName; 

通過:可以設(shè)置默認(rèn)值。如果在配置文件中找不到susan.test.userName的配置,則注入時用默認(rèn)值。

如果在配置文件中找不到susan.test.userName的配置,也沒有設(shè)置默認(rèn)值,則啟動項目時會報錯。

8.2 #{}

主要用于通過spring的EL表達式,獲取bean的屬性,或者調(diào)用bean的某個方法。還有調(diào)用類的靜態(tài)常量和靜態(tài)方法。

  1. @Value("#{roleService.DEFAULT_AGE}"
  2. private int myAge; 
  3.  
  4. @Value("#{roleService.id}"
  5. private int id; 
  6.  
  7. @Value("#{roleService.getRoleName()}"
  8. private String myRoleName; 
  9.  
  10. @Value("#{T(java.lang.Math).random()}"
  11. private double randomValue; 

如果是調(diào)用類的靜態(tài)方法,則需要加T(包名 + 方法名稱)。

例如:T(java.lang.Math)。

好了,今天的內(nèi)容就介紹到這里,希望對你會有所幫助。隨便劇透一下,后面的文章會繼續(xù)介紹:

  1. @Value的原理
  2. @Value動態(tài)刷新屬性值的原因
  3. @ConfigurationProperties注解的用法,它也非常強大。

 

責(zé)任編輯:姜華 來源: 蘇三說技術(shù)
相關(guān)推薦

2021-01-19 05:29:41

代碼Git 工作流

2021-03-26 10:48:14

代碼語言提交

2024-06-18 08:46:06

2021-09-09 08:47:52

Dependency 安全漏洞工具

2021-06-11 06:45:32

SQL結(jié)構(gòu)化語言

2024-03-21 08:21:34

Java 22Java 語言開發(fā)工具包

2024-05-24 08:35:00

Angular 18版本更新

2023-10-20 10:11:00

Nuxt 3.8前端

2022-01-25 12:14:39

面試try-catch代碼

2022-03-18 08:16:51

微軟Windows 11

2024-04-23 10:29:44

SassCSS前端

2010-05-10 17:21:26

Unix操作系統(tǒng)

2021-07-15 05:26:22

Windows 10操作系統(tǒng)微軟

2022-06-24 06:32:46

iOS 16Beta 2

2024-03-08 06:58:55

TypeScript類型縮小模塊解析

2021-05-14 05:20:45

Windows10操作系統(tǒng)微軟

2024-04-09 10:10:23

GridCSS網(wǎng)格

2019-11-26 14:11:52

互聯(lián)網(wǎng)裁員員工

2020-03-03 13:55:38

騰訊手機QQ

2021-02-01 08:16:14

ChromeNode.js
點贊
收藏

51CTO技術(shù)棧公眾號