亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot中的Bean裝配詳解

 更新時(shí)間:2024年04月16日 11:43:22   作者:Java碼農(nóng)探花  
Spring?IoC?容器是一個(gè)管理?Bean?的容器,在?Spring?的定義中,它要求所有的?IoC?容器都需要實(shí)現(xiàn)接口?BeanFactory,它是一個(gè)頂級(jí)容器接口,這篇文章主要介紹了SpringBoot中的Bean裝配詳解,需要的朋友可以參考下

前言

IoC((Inversion of Control,控制反轉(zhuǎn))容器是 Spring 的核心,可以說(shuō) Spring 是一種基于 IoC容器編程的框架。因?yàn)镾pring Boot 是基于注解的開(kāi)發(fā) Spring IoC, 所以我們就從全注解的方式來(lái)講訴Bean裝配。

一、IoC容器的簡(jiǎn)介

Spring IoC 容器是一個(gè)管理 Bean 的容器,在 Spring 的定義中,它要求所有的 IoC 容器都需要實(shí)現(xiàn)接口 BeanFactory,它是一個(gè)頂級(jí)容器接口。 我們從源碼講訴。

BeanFactory接口源碼

package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
public interface BeanFactory {
	// 前綴
    String FACTORY_BEAN_PREFIX = "&";
	// 多個(gè)getBean方法
    Object getBean(String name) throws BeansException;
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    Object getBean(String name, Object... args) throws BeansException;
    <T> T getBean(Class<T> requiredType) throws BeansException;
    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
    <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
    <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
	// 是否包含Bean
    boolean containsBean(String name);
	//是否單例
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
	// 是否原型
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
	// 是否類(lèi)型匹配
    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
	// 獲取Bean的類(lèi)型
    @Nullable
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;
	// 獲取Bean的別名
    @Nullable
    Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;
    String[] getAliases(String name);
}

分析:

  • 上訴源碼中加入了中文注釋?zhuān)ㄟ^(guò)它們就可以理解這些方法的含義。
  • 這里值得注意的是接口中的幾個(gè)方法:
    • 首先我們看到了多個(gè)getBean 方法,這也是IoC 容器最重要的方法之一, 它的意義是從IoC 容器中獲取Bean而從多個(gè)getBean方法中可以看到有按類(lèi)型(bytype)獲取Bean 的,也有按名稱(chēng)(by name)獲取 Bean 的,這就意味著在 Spring IoC 容器中,允許我們按類(lèi)型或者名稱(chēng)獲取 Bean。這對(duì)理解后面將講到的Spring 的依賴(lài)注入(Dependency Injection, DI) 是十分重要的。
    • isSingleton 方法則判斷 Bean 是否在 Spring IoC 中為單例。這里需要記住的是在 Spring IoC 容器中,默認(rèn)的情況下, Bean 都是以單例存在的,也就是使用 getBean 方法返回的都是同一個(gè)對(duì)象。與isSingleton 方法相反的是 isPrototype 方法,如果它返回的是 true,那么當(dāng)我們使用 getBean 方法獲取Bean 的時(shí)候, Spring IoC 容器就會(huì)創(chuàng)建一個(gè)新的 Bean 返回給調(diào)用者。

由于BeanFactory 的功能還不夠強(qiáng)大,因此 Spring 在 BeanFactory 的基礎(chǔ)上, 還設(shè)計(jì)了一個(gè)更為高級(jí)的接口 ApplicationContext。 它是 BeanFactory 的子接口之一, 在 Spring 的體系中 BeanFactory 和ApplicationContext 是最為重要的接口設(shè)計(jì),在現(xiàn)實(shí)中我們使用的大部分 Spring IoC 容器是ApplicationContext 接口的實(shí)現(xiàn)類(lèi)。

  1. 在圖中可以看到, ApplicationContext 接口通過(guò)繼承上級(jí)接口,進(jìn)而繼承 BeanFactory 接口, 但是在BeanFactory 的基礎(chǔ)上,擴(kuò)展了消息國(guó)際化接口(MessageSource)、環(huán)境可配置接口 (EnvironmentCapable)、應(yīng)用事件發(fā)布接口(ApplicationEventPublish巳r) 和資源模式解析接口(ResourcePatternResolver),所以它的功能會(huì)更為強(qiáng)大。
  2. 在Spring Boot 當(dāng)中我們主要是通過(guò)注解來(lái)裝配Bean到 Spring IoC 容器中,為了貼近 SpringBoot 的需要, 這里不再介紹與 XML 相關(guān)的 IoC 容器,而主要介紹一個(gè)基于注解的 IoC 容器,它就是AnnotationConfigApplicationContext,從名稱(chēng)就可以看出它是一個(gè)基于注解的 IoC 容器。 之所以研究它, 是因?yàn)镾pring Boot 裝配和獲取 Bean 的方法與它如出一轍。

例:創(chuàng)建一個(gè)User類(lèi),然后使用AnnotationConfigApplicationContext構(gòu)建IoC容器

public class User {
	private Long id; 
	private String userName; 
/**setter and getter **/ 
}
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Con f工guration ;
import com.springboot.chapter3.po] o.User;
@Configuration 
public class AppConfig { 
	@Bean(name =”user” } 
	public User ini tUser () { 
		User user= new User (); 
		user. set Id (1L) ; 
		user.setUserName (”aa”); 
		return user;
	}
}

@Configuration 代表這是一個(gè) Java 配置文件, Spring 的容器會(huì)根據(jù)它來(lái)生成IoC 容器去裝配Bean;@Bean 代表將 initUser 方法返回的 POJO 裝配到 IoC 容器中,而其屬性name 定義這個(gè) Bean 的名稱(chēng)如果沒(méi)有配置它,則將方法名稱(chēng)“initUser”作為 Bean 的名稱(chēng)保存到Spring IoC 容器中。

import org.apache. log4j .Logger; 
import org. springframework.context.ApplicationContext; 
import org. springframework.context annotation.AnnotationConfigApplicat工onContext;
import com.springboot.chapter3.po] o .User;
public class IoCTest { 
	private static Logger log= Logger.getLogger(IoCTest.class); 
	publ工c static 飛roid main (String [] args) { 
		ApplicationContext ctx = new AnnotationConfigAppl豐cationContext(AppConfig. class);
 		User user= ctx.getBean(User.class); 
	}
}

代碼中將Java 配置文件 AppConfig 傳遞給 AnnotationConfigApplicationContext 的構(gòu)造方法,這樣它就能夠讀取配置了。然后將配置里面的Bean裝配到IoC容器中,于是可以使用 getBean方法獲取對(duì)應(yīng)的POJO。

二、Bean裝配

掃描裝配

上訴講訴的User對(duì)象裝配就是使用@Bean裝配。但是如果一個(gè)個(gè)的 Bean 使用注解@Bean 注入 Spring loC 容器中,那將是一件很麻煩的事情。好在Spring 還允許我們進(jìn)行掃描裝配 Bean 到 loC 容器中,對(duì)于掃描裝配而言使用的注解是@Component和@ComponentScan。@Component 是標(biāo)明l哪個(gè)類(lèi)被掃描進(jìn)入 Spring IoC 容器,而ComponentScan則是標(biāo)明采用何種策略去掃描裝配Bean。

@Component(”user") 
public class User { 
	@Value("1") 
	private Long id; 
	@Value("aa"} 
	private String userName; 
/**setter and getter **/ 
}

這里的注解@Component表明這個(gè)類(lèi)將被SpringIoC 容器掃描裝配,其中配置的“user"則是作為Bean 的名稱(chēng),當(dāng)然你也可以不配置這個(gè)字符串,那么IoC容器就會(huì)把類(lèi)名第一個(gè)字母作為小寫(xiě),其他不變作為Bean 名稱(chēng)放入到IoC 容器中;注解@Value則是指定具體的值,使得Spring IoC給予對(duì)應(yīng)的屬性注入對(duì)應(yīng)的值。為了讓SpringIoC 容器裝配這個(gè)類(lèi), 需要改造類(lèi)AppConfig:

import org.springframework.context.annotat工on.ComponentScan;
import org.springframework.context.annotation Configuration; 
@Configuration 
@ComponentScan 
public class AppConfig {
}

這里加入了@ComponentScan,意味著它會(huì)進(jìn)行掃描,但是它只會(huì)掃描類(lèi)AppConfig所在的當(dāng)前包和其子包。也就是@ComponentScan默認(rèn)掃描當(dāng)前類(lèi)所在包及其子包。 所以User類(lèi)的位置要注意。

測(cè)試:

Applicat工onContext ctx = new AnnotationConfigApplicationContext{AppConfig.class) ;
User user= ctx.getBean(User.class); 
log. info(user.getid());

為了更加合理,@ComponentScan還允許我們自定義掃描的包,我們看一下源碼:

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.beans.factory.support.BeanNameGenerator;
import org.springframework.core.annotation.AliasFor;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
//在一個(gè)類(lèi)中可重復(fù)定義
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
	// 定義掃描的包
    @AliasFor("basePackages")
    String[] value() default {};
	//定義掃描的包
    @AliasFor("value")
    String[] basePackages() default {};
	//定義掃描的類(lèi)
    Class<?>[] basePackageClasses() default {};
	//Bean name生成器
    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
	//作用域解析器
    Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
	//作用域代理模式
    ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
	//資源匹配模式
    String resourcePattern() default "**/*.class";
	//是否啟用默認(rèn)的過(guò)濾器
    boolean useDefaultFilters() default true;
	//當(dāng)滿(mǎn)足過(guò)濾器的條件時(shí)掃描
    Filter[] includeFilters() default {};
	//當(dāng)不滿(mǎn)足過(guò)濾器的條件時(shí)掃描
    Filter[] excludeFilters() default {};
	//是否延遲初始化
    boolean lazyInit() default false;
	//定義過(guò)濾器
    @Retention(RetentionPolicy.RUNTIME)
    @Target({})
    public @interface Filter {
   		//過(guò)濾器類(lèi)型,可以按注解類(lèi)型或者正則式等過(guò)濾
        FilterType type() default FilterType.ANNOTATION;
		//定義過(guò)濾的類(lèi)
        @AliasFor("classes")
        Class<?>[] value() default {};
        @AliasFor("value")
        Class<?>[] classes() default {};
		//匹配方式
        String[] pattern() default {};
    }
}

分析:

  • 首先可以通過(guò)配置項(xiàng)basePackages定義掃描的包名,在沒(méi)有定義的情況下,它只會(huì)掃描當(dāng)前包和其子包下的路徑:還可以通過(guò)basePackageClasses 定義掃描的類(lèi);
  • 其中還有 includeFilters 和 excludeFilters, includeFilters 是定義滿(mǎn)足過(guò)濾器(Filter)條件的 Bean 才去掃描, excludeFilters 則是排除過(guò)濾器條件的 Bean,它們都需要通過(guò)一個(gè)注解@Filter 去定義,它有一個(gè)type 類(lèi)型,這里可以定義為注解或者正則式等類(lèi)型。 classes定義注解類(lèi), pattern 定義正則式類(lèi)

所以得出三個(gè)掃描路徑表示:

@ComponentScan ("com.springboot.example.* ")
@ComponentScan(basePackages = {"com.springboot.example.pojo"})
@ComponentScan(basePackageClasses = {User.class} ) 

以及排除掃描包或類(lèi),讓其不被裝配:

//掃描example下所有包除了@Service裝配的類(lèi)
//這樣,由于加入了 excludeFilters 的配置,使標(biāo)注了@Service 的類(lèi)將不被 IoC 容器掃描注入,這樣就可以把它類(lèi)排除到 Spring IoC容器中了。
@ComponentScan(basePackages = {"com.dragon.restart"},excludeFilters = {@ComponentScan.Filter(classes = Service.class)})

探索啟動(dòng)類(lèi)

事實(shí)上,之前在 Spring Boot 的注解@SpringBootApplication 也注入了@ComponentScan,這里不妨探索其源碼:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
//自定義排除的掃描類(lèi)
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
	//通過(guò)類(lèi)型排除自動(dòng)配置
    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    Class<?>[] exclude() default {};
	//通過(guò)名稱(chēng)排除自動(dòng)配置類(lèi)
    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    String[] excludeName() default {};
	//定義掃描包
    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};
	//定義被掃描的類(lèi)
    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};

顯然,通過(guò)它就能夠定義掃描哪些包。但是這里需要特別注意的是,它提供的exclude和excludeName兩個(gè)方法是對(duì)于其內(nèi)部的自動(dòng)配置類(lèi)才會(huì)生效的。為了能夠排除其他類(lèi),還可以再加入@ComponentScan以達(dá)到我們的目的。

條件裝配

  • 例如在數(shù)據(jù)庫(kù)連接池的配置中漏掉一些配置會(huì)造成數(shù)據(jù)源不能連接上。 在這樣的情況下, IoC容器如果還進(jìn)行數(shù)據(jù)源的裝配, 則系統(tǒng)將會(huì)拋出異常,導(dǎo)致應(yīng)用無(wú)法繼續(xù)。這時(shí)倒是希望IoC容器不去裝配數(shù)據(jù)源。
  • 為了處理這樣的場(chǎng)景, Spring 提供了@Conditional注解幫助我們,而它需要配合另外一個(gè)接口Condition(org.springframework.context.annotation.Condition )來(lái)完成對(duì)應(yīng)的功能。

裝配的Bean:

@Bean(name = "dataSource", destroyMethod = "close" ) 
@Conditional(DatabaseConditional.class)
public DataSource getDataSource ( 
@Value("${database.driverName}") String driver, 
@Value("${database.url}") String url, 
@Value("${database.username}") String username, 
@Value("{database.password}") String password 
){ 
	Properties props= new Properties(); 
	props.setProperty("driver", driver); 
	props setProperty("url", url); 
	props.setProperty("username", username); 
	props setProperty("password", password); 
	DataSource dataSource = null; 
	try { 
		dataSource = BasicDataSourceFactory.createDataSource(props) ; 
	) catch (Exception e) { 
		e.printStackTrace();
	}
	return dataSource;
}

自定義DatabaseConditional類(lèi):

public class DatabaseConditional implements Condition { 
/**
* 數(shù)據(jù)庫(kù)裝配條件
* 
* @param context 條件上下文
* @param metadata 注釋類(lèi)型的元數(shù)據(jù)
* @return true 裝配 Bean,否則不裝配
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 
	//取出環(huán)境配置
	Environment env = context.getEnvironment(); 
	//判斷屬性文件是否存在對(duì)應(yīng)的數(shù)據(jù)庫(kù)配置
	return env.containsProperty(”database.driverName” ) 
		&& env.containsProperty(”database.url”) 
		&& env.containsProperty(” database.username”) 
		&& env.containsProperty (”database.password");

matches 方法首先讀取其上下文環(huán)境, 然后判定是否已經(jīng)配置了對(duì)應(yīng)的數(shù)據(jù)庫(kù)信息。這樣,當(dāng)這些都己經(jīng)配置好后則返回true。這個(gè)時(shí)候Spring會(huì)裝配數(shù)據(jù)庫(kù)連接池的Bean,否則是不裝配的。

自定義Bean

  • 現(xiàn)實(shí)的Java 的應(yīng)用往往需要引入許多來(lái)自第三方的包, 并且很有可能希望把第三方包的類(lèi)對(duì)象也放入到Spring IoC 容器中,這時(shí)@Bean注解就可以發(fā)揮作用了。
  • 例如,要引入一個(gè)DBCP數(shù)據(jù)源,我們先在pom.xml上加入項(xiàng)目所需要DBCP包和數(shù)據(jù)庫(kù)MySQL驅(qū)動(dòng)程序的依賴(lài)。
<dependency> 
	<groupid>org.apache.commons</groupid> 
	<artifactid>commons-dbcp2</artifactid> 
</dependency> 
<dependency> 
	<groupid>mysql</groupid> 
	<artifactid>mysql-connector-ava</artifactid>
</dependency>

這樣 DBCP 和數(shù)據(jù)庫(kù)驅(qū)動(dòng)就被加入到了項(xiàng)目中,接著將使用它提供的機(jī)制來(lái)生成數(shù)據(jù)源:

@Bean(name = "dataSource") 
@Conditional(DatabaseConditional.class)
public DataSource getDataSource (){ 
	Properties props= new Properties(); 
	props.setProperty("driver", driver); 
	props setProperty("url", url); 
	props.setProperty("username", username); 
	props setProperty("password", password); 
	DataSource dataSource = null; 
	try { 
		dataSource = BasicDataSourceFactory.createDataSource(props) ; 
	) catch (Exception e) { 
		e.printStackTrace();
	}
	return dataSource;
}

這里通過(guò)@Bean 定義了其配置項(xiàng) name 為“dataSource“,那么 Spring 就會(huì)把它返回的對(duì)象用名稱(chēng)“dataSource” 保存在 loC 容器中。當(dāng)然, 你也可以不填寫(xiě)這個(gè)名稱(chēng),那么它就會(huì)用你的方法名稱(chēng)作為Bean 名稱(chēng)保存到 IoC 容器中。通過(guò)這樣,就可以將第三方包的類(lèi)裝配到SpringIoC容器中了。

總結(jié)

以上就是SpringBoot的Bean裝配的詳細(xì)講解。

到此這篇關(guān)于SpringBoot詳解Bean裝配的文章就介紹到這了,更多相關(guān)SpringBoot Bean裝配內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java代碼讀取properties配置文件的示例代碼

    Java代碼讀取properties配置文件的示例代碼

    這篇文章主要介紹了Java代碼讀取properties配置文件,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • java 操作gis geometry類(lèi)型數(shù)據(jù)方式

    java 操作gis geometry類(lèi)型數(shù)據(jù)方式

    這篇文章主要介紹了java 操作gis geometry類(lèi)型數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 阿里Sentinel支持Spring Cloud Gateway的實(shí)現(xiàn)

    阿里Sentinel支持Spring Cloud Gateway的實(shí)現(xiàn)

    這篇文章主要介紹了阿里Sentinel支持Spring Cloud Gateway的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-04-04
  • springboot加載命令行參數(shù)ApplicationArguments的實(shí)現(xiàn)

    springboot加載命令行參數(shù)ApplicationArguments的實(shí)現(xiàn)

    本文主要介紹了springboot加載命令行參數(shù)ApplicationArguments的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Springboot上傳文件時(shí)提示405問(wèn)題及排坑過(guò)程

    Springboot上傳文件時(shí)提示405問(wèn)題及排坑過(guò)程

    這篇文章主要介紹了Springboot上傳文件時(shí)提示405問(wèn)題及排坑過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Flink實(shí)現(xiàn)特定統(tǒng)計(jì)的歸約聚合reduce操作

    Flink實(shí)現(xiàn)特定統(tǒng)計(jì)的歸約聚合reduce操作

    這篇文章主要介紹了Flink實(shí)現(xiàn)特定統(tǒng)計(jì)的歸約聚合reduce操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-02-02
  • Java讀取網(wǎng)絡(luò)文件的實(shí)例代碼

    Java讀取網(wǎng)絡(luò)文件的實(shí)例代碼

    這篇文章主要介紹了Java讀取網(wǎng)絡(luò)文件的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Kafka多節(jié)點(diǎn)分布式集群搭建實(shí)現(xiàn)過(guò)程詳解

    Kafka多節(jié)點(diǎn)分布式集群搭建實(shí)現(xiàn)過(guò)程詳解

    這篇文章主要介紹了Kafka多節(jié)點(diǎn)分布式集群搭建實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • IDEA中實(shí)體類(lèi)(POJO)與JSON快速互轉(zhuǎn)問(wèn)題

    IDEA中實(shí)體類(lèi)(POJO)與JSON快速互轉(zhuǎn)問(wèn)題

    這篇文章主要介紹了IDEA中實(shí)體類(lèi)(POJO)與JSON快速互轉(zhuǎn),本文通過(guò)圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • java隨機(jī)生成10位數(shù)的字符串ID

    java隨機(jī)生成10位數(shù)的字符串ID

    這篇文章主要為大家詳細(xì)介紹了java隨機(jī)生成10位數(shù)字符串ID的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08

最新評(píng)論