欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring中常見的7種BeanDefinition詳解

 更新時間:2023年09月12日 10:48:26   作者:江南一點雨  
在?Spring?容器中,我們廣泛使用的是一個一個的?Bean,BeanDefinition?從名字上就可以看出是關(guān)于?Bean?的定義,下面就跟隨小編一起深入了解一下常見的7中BeanDefinition吧

今天我們繼續(xù)來看 Spring 源碼中一個非常重要的概念:BeanDefinition。

1.BeanDefinition

在 Spring 容器中,我們廣泛使用的是一個一個的 Bean,BeanDefinition 從名字上就可以看出是關(guān)于 Bean 的定義。

事實上就是這樣,我們在 XML 文件中配置的 Bean 的各種屬性,亦或者用注解定義出來的 Bean 的各種屬性,在真正生成 Bean 直接,我們需要先對這些設(shè)置的屬性進(jìn)行解析,解析的結(jié)果需要有一個對象來承載,很明顯,這個對象就是 BeanDefinition。

無論是通過 XML 中定義的 Bean 屬性還是通過 Java 代碼定義的 Bean 屬性,都會先加載到 BeanDefinition 上,然后通過 BeanDefinition 來生成一個 Bean,從這個角度來說,BeanDefinition 和 Bean 的關(guān)系有點類似于類和對象的關(guān)系,BeanDefinition 是模板,Bean 是模板具體化之后的產(chǎn)物。

要理解 BeanDefinition,我們從 BeanDefinition 的繼承關(guān)系開始看起。

BeanDefinition 是一個接口,繼承自 BeanMetadataElement 和 AttributeAccessor 接口。

  • BeanMetadataElement:該接口只有一個方法 getSource,該方法返回 Bean 的來源。
  • AttributeAccessor:該接口主要規(guī)范了問任意對象元數(shù)據(jù)的方法。

我們來看下 AttributeAccessor:

public?interface?AttributeAccessor?{
?void?setAttribute(String?name,?@Nullable?Object?value);
?@Nullable
?Object?getAttribute(String?name);
?@Nullable
?Object?removeAttribute(String?name);
?boolean?hasAttribute(String?name);
?String[]?attributeNames();
}

這里定義了元數(shù)據(jù)的訪問接口,具體的實現(xiàn)則是 AttributeAccessorSupport,這些數(shù)據(jù)采用 LinkedHashMap 進(jìn)行存儲。

這是 BeanDefinition 所繼承的兩個接口。接下來我們來看下 BeanDefinition 接口:

public?interface?BeanDefinition?extends?AttributeAccessor,?BeanMetadataElement?{
?String?SCOPE_SINGLETON?=?ConfigurableBeanFactory.SCOPE_SINGLETON;
?String?SCOPE_PROTOTYPE?=?ConfigurableBeanFactory.SCOPE_PROTOTYPE;
?int?ROLE_APPLICATION?=?0;
?int?ROLE_SUPPORT?=?1;
?int?ROLE_INFRASTRUCTURE?=?2;
?void?setParentName(@Nullable?String?parentName);
?@Nullable
?String?getParentName();
?void?setBeanClassName(@Nullable?String?beanClassName);
?@Nullable
?String?getBeanClassName();
?void?setScope(@Nullable?String?scope);
?@Nullable
?String?getScope();
?void?setLazyInit(boolean?lazyInit);
?boolean?isLazyInit();
?void?setDependsOn(@Nullable?String...?dependsOn);
?@Nullable
?String[]?getDependsOn();
?void?setAutowireCandidate(boolean?autowireCandidate);
?boolean?isAutowireCandidate();
?void?setPrimary(boolean?primary);
?boolean?isPrimary();
?void?setFactoryBeanName(@Nullable?String?factoryBeanName);
?@Nullable
?String?getFactoryBeanName();
?void?setFactoryMethodName(@Nullable?String?factoryMethodName);
?@Nullable
?String?getFactoryMethodName();
?ConstructorArgumentValues?getConstructorArgumentValues();
?default?boolean?hasConstructorArgumentValues()?{
??return?!getConstructorArgumentValues().isEmpty();
?}
?MutablePropertyValues?getPropertyValues();
?default?boolean?hasPropertyValues()?{
??return?!getPropertyValues().isEmpty();
?}
?void?setInitMethodName(@Nullable?String?initMethodName);
?@Nullable
?String?getInitMethodName();
?void?setDestroyMethodName(@Nullable?String?destroyMethodName);
?@Nullable
?String?getDestroyMethodName();
?void?setRole(int?role);
?int?getRole();
?void?setDescription(@Nullable?String?description);
?@Nullable
?String?getDescription();
?ResolvableType?getResolvableType();
?boolean?isSingleton();
?boolean?isPrototype();
?boolean?isAbstract();
?@Nullable
?String?getResourceDescription();
?@Nullable
?BeanDefinition?getOriginatingBeanDefinition();
}

BeanDefinition 中的方法雖然多,但是結(jié)合我們平時在 XML/Java 中的配置,這些方法其實都很好理解:

  • 首先一開始定義了兩個變量用來描述 Bean 是不是單例的,后面的 setScope/getScope 方法可以用來修改/獲取 scope 屬性。
  • ROLE_xxx 用來描述一個 Bean 的角色,ROLE_APPLICATION 表示這個 Bean 是用戶自己定義的 Bean;ROLE_SUPPORT 表示這個 Bean 是某些復(fù)雜配置的支撐部分;ROLE_INFRASTRUCTURE 表示這是一個 Spring 內(nèi)部的 Bean,通過 setRole/getRole 可以修改。
  • setParentName/getParentName 用來配置 parent 的名稱,這塊可能有的小伙伴使用較少,這個對應(yīng)著 XML 中的 <bean parent=""> 配置,在之前的視頻中松哥已經(jīng)和大家講過了 Spring 中 parent 的使用了。
  • setBeanClassName/getBeanClassName 這個就是配置 Bean 的 Class 全路徑,對應(yīng) XML 中的 <bean class=""> 配置。
  • setLazyInit/isLazyInit 配置/獲取 Bean 是否懶加載,這個對應(yīng)了 XML 中的 <bean lazy-init=""> 配置。
  • setDependsOn/getDependsOn 配置/獲取 Bean 的依賴對象,這個對應(yīng)了 XML 中的 <bean depends-on=""> 配置。
  • setAutowireCandidate/isAutowireCandidate 配置/獲取 Bean 是否是自動裝配,對應(yīng)了 XML 中的 <bean autowire-candidate=""> 配置。
  • setPrimary/isPrimary 配置/獲取當(dāng)前 Bean 是否為首選的 Bean,對應(yīng)了 XML 中的 <bean primary=""> 配置。
  • setFactoryBeanName/getFactoryBeanName 配置/獲取 FactoryBean 的名字,對應(yīng)了 XML 中的 <bean factory-bean=""> 配置。
  • setFactoryMethodName/getFactoryMethodName 和上一條成對出現(xiàn)的,對應(yīng)了 XML 中的 <bean factory-method=""> 配置,不再贅述。
  • getConstructorArgumentValues 返回該 Bean 構(gòu)造方法的參數(shù)值。
  • hasConstructorArgumentValues 判斷上一條是否是空對象。
  • getPropertyValues 這個是獲取普通屬性的集合。
  • hasPropertyValues 判斷上一條是否為空對象。
  • setInitMethodName/setDestroyMethodName 配置 Bean 的初始化方法、銷毀方法。
  • setDescription/getDescription 配置/返回 Bean 的描述。
  • isSingleton Bean 是否為單例。
  • isPrototype Bean 是否為原型。
  • isAbstract Bean 是否抽象。
  • getResourceDescription 返回定義 Bean 的資源描述。
  • getOriginatingBeanDefinition 如果當(dāng)前 BeanDefinition 是一個代理對象,那么該方法可以用來返回原始的 BeanDefinition 。

這個就是 BeanDefinition 的定義以及它里邊方法的含義。

2.BeanDefinition 實現(xiàn)類

上面只是 BeanDefinition 接口的定義,BeanDefinition 還擁有諸多實現(xiàn)類,我們也來大致了解下。

先來看一張繼承關(guān)系圖:

這么多實現(xiàn)類看著有點眼花繚亂,不過搞清楚了每一個接口和類的作用,再看就很容易了。

2.1 AbstractBeanDefinition

AbstractBeanDefinition 是一個抽象類,它根據(jù) BeanDefinition 中定義的接口提供了相應(yīng)的屬性,并實現(xiàn)了 BeanDefinition 中定義的一部分方法。BeanDefinition 中原本只是定義了一系列的 get/set 方法,并沒有提供對應(yīng)的屬性,在 AbstractBeanDefinition 中將所有的屬性定義出來了。

后面其他的實現(xiàn)類也基本上都是在 AbstractBeanDefinition 的基礎(chǔ)上完成的。

2.2 RootBeanDefinition

這是一個比較常用的實現(xiàn)類,對應(yīng)了一般的元素標(biāo)簽。

2.3 ChildBeanDefinition

可以讓子 BeanDefinition 定義擁有從父 BeanDefinition 那里繼承配置的能力,如果子 Bean 從父 Bean 獲取配置,可以參考松哥之前的這篇文章:Spring BeanDefinition 也分父子?。

2.4 GenericBeanDefinition

GenericBeanDefinition 是從 Spring2.5 以后新加入的 BeanDefinition 實現(xiàn)類。GenericBeanDefinition 可以動態(tài)設(shè)置父 Bean,同時兼具 RootBeanDefinition 和 ChildBeanDefinition 的功能,因此,自從有了 GenericBeanDefinition 之后,RootBeanDefinition 和 ChildBeanDefinition 現(xiàn)在相對就用的少了。

2.5 AnnotatedBeanDefinition

這個表示注解類型 BeanDefinition,用于表示通過注解配置的 Bean 定義。通過 AnnotatedBeanDefinition,我們可以獲取到被注解的 Bean 的相關(guān)信息,包括注解類型、屬性值、方法等。這個接口提供了一種方便的方式來處理通過注解方式配置的 Bean,并且可以在運行時動態(tài)地獲取和操作這些注解信息,當(dāng)然,這是一個接口,它有三個實現(xiàn)類,分別是 AnnotatedGenericBeanDefinition、ScannedGenericBeanDefinition 以及 ConfigurationClassBeanDefinition。

2.6 AnnotatedGenericBeanDefinition

使用了 @Configuration 注解標(biāo)記配置類會解析為 AnnotatedGenericBeanDefinition。

2.7 ScannedGenericBeanDefinition

這個是通過包掃描自動注冊的 Bean,就會被解析為 ScannedGenericBeanDefinition。

2.8 ConfigurationClassBeanDefinition

這是一個私有的內(nèi)部類。我們通過 @Bean 注解定義的 Bean,最終會被解析為 ConfigurationClassBeanDefinition。

2.9 ClassDerivedBeanDefinition

ClassDerivedBeanDefinition 的作用是擴(kuò)展并描述一個類派生的Bean的元數(shù)據(jù)。它是 AnnotatedBeanDefinition 接口的一個實現(xiàn)類,在 Spring 框架中用于表示通過類派生方式配置的Bean定義。

2.10 CreateFromClassBeanDefinition

這個是按照類型創(chuàng)建 Bean 的時候會用到。

差不多就這么多了,大部分我們?nèi)粘i_發(fā)中其實都用不上,接下來松哥通過幾個具體的案例來和小伙伴們演示這些 BeanDefinition 的具體用法。后面的文章,我們再來分析這些 BeanDefinition 在 Spring 源碼中是如何應(yīng)用的。

3.實踐

接下來我通過幾個具體的案例來和小伙伴們演示各種不同的 BeanDefinition 的用法,今天我主要和小伙伴們演示我們純手動使用 BeanDefinition,然后分析一下我們平時的配置本質(zhì)上使用的 BeanDefinition 是哪一個,今天我們先不去源碼分析,單純的就看看效果。

3.1 GenericBeanDefinition

先來看 GenericBeanDefinition,這個功能相對比較全,兼具 RootBeanDefinition 和 ChildBeanDefinition 的能力。

先來看一個簡單用法:

DefaultListableBeanFactory?beanFactory?=?new?DefaultListableBeanFactory();
GenericBeanDefinition?bd?=?new?GenericBeanDefinition();
bd.setBeanClass(User.class);
MutablePropertyValues?pValues?=?new?MutablePropertyValues();
pValues.add("username",?"javaboy");
bd.setPropertyValues(pValues);
beanFactory.registerBeanDefinition("user",?bd);
User?user?=?beanFactory.getBean("user",?User.class);
System.out.println("user?=?"?+?user);

小伙伴們看到,我們這里向 Spring 容器注冊了一個 GenericBeanDefinition 類型的 BeanDefinition,GenericBeanDefinition 中包含了具體的 class 以及 Bean 的各個屬性值。

如果我們在 Bean 定義的時候,想要使用繼承特性,也可以使用 GenericBeanDefinition:

DefaultListableBeanFactory?beanFactory?=?new?DefaultListableBeanFactory();
GenericBeanDefinition?parentBD?=?new?GenericBeanDefinition();
GenericBeanDefinition?childBD?=?new?GenericBeanDefinition();
parentBD.setBeanClass(Animal.class);
MutablePropertyValues?pValues?=?new?MutablePropertyValues();
pValues.add("name",?"小黃");
parentBD.setPropertyValues(pValues);
childBD.setBeanClass(Dog.class);
childBD.setParentName("animal");
beanFactory.registerBeanDefinition("animal",?parentBD);
beanFactory.registerBeanDefinition("dog",?childBD);
Dog?dog?=?beanFactory.getBean("dog",?Dog.class);
System.out.println("dog?=?"?+?dog);

這次我直接定義了兩個 GenericBeanDefinition,一個作為 parent,另外一個作為 child,為 child 設(shè)置 parentName,則 child 可以繼承 parent 中的屬性。上面的案例中,最終打印出來 dog 的 name 屬性就是 小黃,這塊小伙伴們可以參考松哥之前的文章:Spring BeanDefinition 也分父子?。

我們平時通過 XML 文件定義的 Bean,最終解析后就是 GenericBeanDefinition。

例如下面這樣:

<?xml?version="1.0"?encoding="UTF-8"?>
<beans?xmlns="http://www.springframework.org/schema/beans"
???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
???????xsi:schemaLocation="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans.xsd">
????<bean?class="org.javaboy.demo.User"?id="user"></bean>
</beans>

加載 XML 文件,創(chuàng)建容器:

ClassPathXmlApplicationContext?ctx?=?new?ClassPathXmlApplicationContext("beans.xml");
String[]?beanDefinitionNames?=?ctx.getBeanDefinitionNames();
for?(String?beanDefinitionName?:?beanDefinitionNames)?{
????BeanDefinition?bd?=?ctx.getBeanFactory().getBeanDefinition(beanDefinitionName);
????System.out.println(beanDefinitionName?+?">>>"?+?bd.getClass());
}

最終打印結(jié)果如下:

這個也好理解,畢竟我們在 XML 中配置的時候,可能存在 parent,也可能不存在,用 GenericBeanDefinition 就能夠應(yīng)對各種情況。

3.2 RootBeanDefinition/ChildBeanDefinition

這兩個常規(guī)的功能其實都有,但是 RootBeanDefinition 一般可以用來做 parent,不能用作 child,即給 RootBeanDefinition 不能配置 parentName 屬性。強(qiáng)行設(shè)置會拋出如下異常:

@Override
public?void?setParentName(@Nullable?String?parentName)?{
?if?(parentName?!=?null)?{
??throw?new?IllegalArgumentException("Root?bean?cannot?be?changed?into?a?child?bean?with?parent?reference");
?}
}

ChildBeanDefinition 則既可以做 parent 也可以做 child,但是 ChildBeanDefinition 在使用的使用必須指定 parent,即使 ChildBeanDefinition 作為 parent,也必須指定 parent,所以 ChildBeanDefinition 在使用的過程中有一點點局限性,因此目前被 GenericBeanDefinition 代替了。

來看一個簡單的案例:

DefaultListableBeanFactory?beanFactory?=?new?DefaultListableBeanFactory();
RootBeanDefinition?parentBD?=?new?RootBeanDefinition();
parentBD.setBeanClass(Animal.class);
MutablePropertyValues?pValues?=?new?MutablePropertyValues();
pValues.add("name",?"小黃");
parentBD.setPropertyValues(pValues);
ChildBeanDefinition?childBD?=?new?ChildBeanDefinition("animal");
childBD.setBeanClass(Dog.class);
beanFactory.registerBeanDefinition("animal",?parentBD);
beanFactory.registerBeanDefinition("dog",?childBD);
Dog?dog?=?beanFactory.getBean("dog",?Dog.class);
System.out.println("dog?=?"?+?dog);

3.3 AnnotatedGenericBeanDefinition

對于使用 @Configuration 注解標(biāo)記的類,最終解析出來的 BeanDefinition 就是 AnnotatedGenericBeanDefinition。例如我有一個配置類如下:

@Configuration
public?class?JavaConfig?{
}

加載配置類并啟動容器:

AnnotationConfigApplicationContext?ctx?=?new?AnnotationConfigApplicationContext(JavaConfig.class);
String[]?beanDefinitionNames?=?ctx.getBeanDefinitionNames();
for?(String?beanDefinitionName?:?beanDefinitionNames)?{
????BeanDefinition?beanDefinition?=?ctx.getBeanFactory().getBeanDefinition(beanDefinitionName);
????System.out.println(beanDefinitionName?+?"?>>>?"?+?beanDefinition.getClass());
}

最終打印結(jié)果如下:

3.4 ScannedGenericBeanDefinition

這個是那些通過包掃描注冊到 Spring 容器中的 Bean,在一開始定義出來的 BeanDefinition 就是 ScannedGenericBeanDefinition。

例如我有如下 Bean:

@Service
public?class?UserService?{
}

然后配置包掃描:

@Configuration
@ComponentScan
public?class?JavaConfig?{
}

啟動容器:

AnnotationConfigApplicationContext?ctx?=?new?AnnotationConfigApplicationContext(JavaConfig.class);
String[]?beanDefinitionNames?=?ctx.getBeanDefinitionNames();
for?(String?beanDefinitionName?:?beanDefinitionNames)?{
????BeanDefinition?beanDefinition?=?ctx.getBeanFactory().getBeanDefinition(beanDefinitionName);
????System.out.println(beanDefinitionName?+?"?>>>?"?+?beanDefinition.getClass());
}

最終打印結(jié)果如下:

3.5 ConfigurationClassBeanDefinition

當(dāng)我們通過 @Bean 注解去定義 Bean 的時候,那么被 @Bean 注解標(biāo)記的類就會被解析為 ConfigurationClassBeanDefinition。

例如下面這個例子:

@Configuration
public?class?JavaConfig?{
????@Bean
????User?user()?{
????????return?new?User();
????}
}

查看解析后的 BeanDefinition 如下:

3.6 CreateFromClassBeanDefinition

這個其實用的少,但是咱么既然講到 Spring,松哥也說兩句。

這個是當(dāng)我們想要創(chuàng)建一個對象,我們希望這個對象能夠自動走一遍 Spring 中的各種后置處理器的時候,那么可以調(diào)用 createBean 方法,該方法內(nèi)部使用了 CreateFromClassBeanDefinition。

例如如下代碼:

AnnotationConfigApplicationContext?ctx?=?new?AnnotationConfigApplicationContext(JavaConfig.class);
ConfigurableListableBeanFactory?beanFactory?=?ctx.getBeanFactory();
User?user?=?beanFactory.createBean(User.class);
System.out.println("user?=?"?+?user);

使用這種方式去創(chuàng)建一個 Bean,這個 Bean 會走一遍 Spring 中 Bean 的后置處理器,其中,createBean 方法的內(nèi)部就使用了 CreateFromClassBeanDefinition。

3.7 ClassDerivedBeanDefinition

ClassDerivedBeanDefinition 和 CreateFromClassBeanDefinition 其實比較像,差別在于二者處理構(gòu)造方法的方式不同。

而且 ClassDerivedBeanDefinition 是一個相當(dāng)冷門的 BeanDefinition,在 GenericApplicationContext 的實現(xiàn)類中,可以使用 GenericXmlApplicationContext、StaticApplicationContext 或者 GenericGroovyApplicationContext,只有這三個類中 registerBean 方法用到了 ClassDerivedBeanDefinition,我們常見的 AnnotationConfigApplicationContext 由于方法重寫的緣故并未使用 ClassDerivedBeanDefinition。

StaticApplicationContext?ctx?=?new?StaticApplicationContext();
ctx.registerBean(User.class,()->{
????User?user?=?new?User();
????user.setUsername("javaboy");
????return?user;
});
User?user?=?ctx.getBean(User.class);
System.out.println("user?=?"?+?user);
String[]?beanDefinitionNames?=?ctx.getBeanDefinitionNames();
for?(String?beanDefinitionName?:?beanDefinitionNames)?{
????BeanDefinition?bd?=?ctx.getBeanDefinition(beanDefinitionName);
????System.out.println(beanDefinitionName?+?">>>"?+?bd.getClass());
}

我們可以調(diào)用 registerBean 方法向 Spring 容器中注入一個 Bean,該方法第二個參數(shù)是一個 Bean 的生產(chǎn)者,如果不指定生產(chǎn)者,那么這個方法最終就是通過第一個參數(shù)反射創(chuàng)建 Bean,registerBean 方法的內(nèi)部就是使用了 ClassDerivedBeanDefinition。

好啦,BeanDefinition 一共就是這七種,接下來我會通過幾篇文章和大家重點介紹 GenericBeanDefinition、AnnotatedGenericBeanDefinition、ScannedGenericBeanDefinition 以及 ConfigurationClassBeanDefinition 這四種最為常見的 BeanDefinition。

以上就是Spring中常見的7種BeanDefinition詳解的詳細(xì)內(nèi)容,更多關(guān)于Spring BeanDefinition的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java內(nèi)部類知識匯總

    Java內(nèi)部類知識匯總

    在Java中,在類內(nèi)部可以定義成員變量與方法,還可以在類的內(nèi)部定義類.這種在類的內(nèi)部定義的類稱為內(nèi)部類.而內(nèi)部類所在的類稱為外部類.
    2018-03-03
  • Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之哈希算法實現(xiàn)

    Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之哈希算法實現(xiàn)

    哈希表本質(zhì)是一種(key,value)結(jié)構(gòu),由此我們可以聯(lián)想到,能不能把哈希表的key映射成數(shù)組的索引index呢?如果這樣做的話那么查詢相當(dāng)于直接查詢索引,查詢時間復(fù)雜度為O(1),其實這也正是當(dāng)key為int型時的做法,將key通過某種做法映射成index,從而轉(zhuǎn)換成數(shù)組結(jié)構(gòu)
    2022-02-02
  • maven倉庫中心mirrors配置多個下載中心(執(zhí)行最快的鏡像)

    maven倉庫中心mirrors配置多個下載中心(執(zhí)行最快的鏡像)

    這篇文章主要介紹了maven倉庫中心mirrors配置多個下載中心(執(zhí)行最快的鏡像),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java使用反射獲取字段屬性

    Java使用反射獲取字段屬性

    這篇文章主要為大家詳細(xì)介紹了Java如何利用反射實現(xiàn)獲取字段屬性值,文中的示例代碼講解詳細(xì),具有很好的參考價值,希望對大家有所幫助
    2023-06-06
  • 詳解用Eclipse如何創(chuàng)建Web項目

    詳解用Eclipse如何創(chuàng)建Web項目

    本篇文章主要介紹了詳解用Eclipse如何創(chuàng)建Web項目,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • 面試題:java中為什么foreach中不允許對元素進(jìn)行add和remove

    面試題:java中為什么foreach中不允許對元素進(jìn)行add和remove

    讀者遇到了一個比較經(jīng)典的面試題,也就是標(biāo)題上說的,為什么 foreach 中不允許對元素進(jìn)行 add 和 remove,本文就詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-10-10
  • 詳細(xì)解讀JAVA多線程實現(xiàn)的三種方式

    詳細(xì)解讀JAVA多線程實現(xiàn)的三種方式

    本篇文章主要介紹了詳細(xì)解讀JAVA多線程實現(xiàn)的三種方式,主要包括繼承Thread類、實現(xiàn)Runnable接口、使用ExecutorService、Callable、Future實現(xiàn)有返回結(jié)果的多線程。有需要的可以了解一下。
    2016-11-11
  • java使用EasyExcel實現(xiàn)合并單元格

    java使用EasyExcel實現(xiàn)合并單元格

    這篇文章主要為大家詳細(xì)介紹了java使用EasyExcel實現(xiàn)合并單元格的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • Java使用字節(jié)流復(fù)制文件的方法

    Java使用字節(jié)流復(fù)制文件的方法

    這篇文章主要為大家詳細(xì)介紹了Java使用字節(jié)流復(fù)制文件的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 動力節(jié)點_王勇_DRP項目視頻教程完整版292集

    動力節(jié)點_王勇_DRP項目視頻教程完整版292集

    該視頻由國內(nèi)知名講師王勇老師主講,適合掌握J(rèn)ava基礎(chǔ)內(nèi)容的同學(xué)學(xué)習(xí),本視頻共計292集,學(xué)習(xí)Java Web項目,DRP項目視頻是首選,累計下載量已經(jīng)達(dá)到上千萬,很多同學(xué)通過自學(xué)該視頻找到了軟件開發(fā)工作
    2017-04-04

最新評論