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

Spring中初始化泛型類的方法實(shí)例

 更新時(shí)間:2017年01月18日 14:50:24   作者:隔葉黃鶯  
這篇文章主要給大家介紹了Spring中如何初始化泛型類,文中給出詳細(xì)的介紹和方法實(shí)例,對(duì)大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,有需要的朋友可以參考學(xué)習(xí),下面來(lái)一起看看吧。

首先來(lái)看下在 Java 中對(duì)于泛型類型,比如這樣簡(jiǎn)單的類定義

class Processor<T> {}

如果直接初始化時(shí)要指定具體類型的話,我們可以這么寫(xiě)

Processor<String> processor = new Processor<>(); //Java 7 及以上版本

Spring 對(duì)基本泛型的初始化

如果我們要用 Spring 容器來(lái)初始化這個(gè)類,比如給上面那個(gè)類加個(gè) @Named 注解

@Named
class Processor<T> {
}

這時(shí)候我們通過(guò) beanFactory.getBean(Processor.class) 得到的是一個(gè)什么樣的實(shí)例呢?Spring 怎么知道要指定什么具體類型呢?很簡(jiǎn)單,任何不確定的情況都是 Object。所以通過(guò)容器得到的  Processor 實(shí)例相當(dāng)于用下面代碼構(gòu)造出來(lái)的

Processor processor = new Processor(); //更準(zhǔn)確來(lái)講是 Processor<Object> processor = new Processor<>();

再進(jìn)一步,對(duì)于有上限約束的泛型定義,Spring 才如何應(yīng)對(duì)呢?像

@Named
class Processor<T extends Number> {
}

類似的,class Processor<T> 相當(dāng)于 class Processor<T extends Object> , 因此 Spring 在具體類型未明的情況下也是要用最頂層可接受類型,Spring 將會(huì)針對(duì)上面的代碼實(shí)例出下面的對(duì)象

Processor<Number> processor = new Processor<>();

再?gòu)?fù)雜一些,泛型的子類型仍然是泛型的情況,如下代碼

首先定義了一個(gè)泛型接口

public interface Service<T> {
 String process(T t);
}

然后要求 Spring 容器來(lái)初始下面的 NumberService 實(shí)例

@Named
public class NumberService<R extends Number> implements Service<R> {
 
 @Override
 public String process(R number) {
 return "Process Number: " + number; 
 }
}

Spring 在初始化 NumberService 實(shí)例同樣是要取用最頂層可接受類型,通過(guò)下面的代碼來(lái)初始化

NumberService<Number> numberService = new NumberService<>();

再終極一些,泛型類型并且類型也是泛型的,Spring 該如何拿捏?

@Named
public class Processor<T> {
 
 @Inject
 Private Service<T> service;
}

此時(shí) Spring 該如何確定上面的類型 T 呢?因?yàn)橛辛?Service<T> service 屬性的存在而不能再籠統(tǒng)的想像 Spring 會(huì)采用下面的代碼來(lái)初始化 Processor 實(shí)例

Processor<Object> processor = new Processor<>();

而是 Processor 的具體類型必須通過(guò)被注入的 Service<T> 實(shí)例的具體類型來(lái)推斷的,這就取決于在 Spring 容器中存在什么樣的 Service<T> 實(shí)例。舉兩個(gè)例子

如果 Spring 中有初始化

@Named
public class StringService implements Service<String> {
 @Override
 public String process(String string) {
 return "Process String: " + string;
 }
}

那么前面的 Processor<T> 實(shí)例就相當(dāng)于

Processor<String> processor = new Processor<>();
processor.service = new StringService();

如果 Spring 中初始化的 Service<T> 是前面那個(gè) NumberService<R extends Number> implements Service<R> , 那么 Spring 容器中的 Processor<T> 實(shí)例相當(dāng)于

Processor<Number> processor = new Processor<>();
processor.service = new NumberService<Number>();

那如果前面的 NumberService 和 StringService 同時(shí)在 Spring 容器中注冊(cè)了呢?Spring 同樣要為難了,在沒(méi)有 @Primary 的情況下無(wú)法確定使用哪個(gè)實(shí)例來(lái)注入 Service<T> service 屬性了,出現(xiàn)類似錯(cuò)誤

2016-12-09 00:56:50.922 WARN 4950 --- [  main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'processor': Unsatisfied dependency expressed through field 'service'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'cc.unmi.Service<?>' available: expected single matching bean but found 2: numberService,stringService
2016-12-09 00:56:50.941 ERROR 4950 --- [  main] o.s.b.d.LoggingFailureAnalysisReporter :

***************************
APPLICATION FAILED TO START
***************************

Description:

Field service in cc.unmi.Processor required a single bean, but 2 were found:
 - numberService: defined in file [/Users/Yanbin/Workspaces/github/spring-generic-demo/target/classes/cc/unmi/NumberService.class]
 - stringService: defined in file [/Users/Yanbin/Workspaces/github/spring-generic-demo/target/classes/cc/unmi/StringService.class]

Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

這和普通屬性的注入時(shí)有多個(gè)可選實(shí)例時(shí)是一樣的錯(cuò)誤。

總結(jié)一下

如果 Spring 在初始化泛型類時(shí),未提供任何具體類型則會(huì)采用最上限的類型來(lái)初始化實(shí)例

  1. @Named class Processor<T>  ->  new Processor<Object>()
  2. @Named class Processor<T extends Number> -> new Processor<Number>();

如果泛型類型與被注入的屬性的具體類型有關(guān)聯(lián),則由屬性類型推斷出主類型

@Named class Processor<T> {
 @Inject Service<T> service;
}

此時(shí) Spring 容器中存在 class StringService implements Service<String> 的實(shí)例,則會(huì)由屬性 service(StringService 實(shí)例) 推斷出 Processor 的具體類型是 Processor<String>

當(dāng)然這個(gè) Processor 類也是可以定義的稍復(fù)雜一些,如

@Named class Processor<T extends Number> {
 @Inject Service<T> service;
}

關(guān)于本文的示例代碼可參考 https://github.com/yabqiu/spring-generic-demo, 請(qǐng)運(yùn)行 mvn spring-boot:run 查看輸出結(jié)果來(lái)理解 Spring 怎么去初始化泛型類實(shí)例的。

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家學(xué)習(xí)或者使用Spring能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。

相關(guān)文章

  • 從dubbo zookeeper注冊(cè)地址提取出zookeeper地址的方法

    從dubbo zookeeper注冊(cè)地址提取出zookeeper地址的方法

    今天小編就為大家分享一篇關(guān)于從dubbo zookeeper注冊(cè)地址提取出zookeeper地址的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • 解決swaggerUI頁(yè)面沒(méi)有顯示Controller方法的坑

    解決swaggerUI頁(yè)面沒(méi)有顯示Controller方法的坑

    這篇文章主要介紹了解決swaggerUI頁(yè)面沒(méi)有顯示Controller方法的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java程序中的延遲加載功能使用

    Java程序中的延遲加載功能使用

    這篇文章主要介紹了Java程序中的延遲加載功能使用,一定程度上有助于提升性能和降低內(nèi)存使用率,需要的朋友可以參考下
    2015-07-07
  • 使用jdk7的nio2操作文件拷貝和剪切示例

    使用jdk7的nio2操作文件拷貝和剪切示例

    使用jdk7的NIO2進(jìn)行文件或文件夾的拷貝移動(dòng)操作??梢宰詣?dòng)創(chuàng)建路徑,差異化更新文件,簡(jiǎn)單的出錯(cuò)重連機(jī)制
    2014-01-01
  • springboot啟動(dòng)流程過(guò)程

    springboot啟動(dòng)流程過(guò)程

    Spring Boot 簡(jiǎn)化了 Spring 框架的使用,通過(guò)創(chuàng)建 `SpringApplication` 對(duì)象,判斷應(yīng)用類型并設(shè)置初始化器和監(jiān)聽(tīng)器,在 `run` 方法中,讀取配置并加載到 `Environment` 中,通過(guò) Spring 事件機(jī)制和 `EnvironmentPostProcessor` 處理配置
    2025-02-02
  • SpringBoot 多線程事務(wù)回滾的實(shí)現(xiàn)

    SpringBoot 多線程事務(wù)回滾的實(shí)現(xiàn)

    本文是基于springboot的@Async注解開(kāi)啟多線程,并通過(guò)自定義注解和AOP實(shí)現(xiàn)的多線程事務(wù),避免繁瑣的手動(dòng)提交/回滾事務(wù),感興趣的可以了解一下
    2024-02-02
  • java實(shí)現(xiàn)留言板功能實(shí)例

    java實(shí)現(xiàn)留言板功能實(shí)例

    這篇文章主要為大家詳細(xì)介紹了JSP+JavaBean的留言板技術(shù) ,JavaWeb登陸功能實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • JPA之多對(duì)多查詢死循環(huán)嵌套問(wèn)題及解決方案

    JPA之多對(duì)多查詢死循環(huán)嵌套問(wèn)題及解決方案

    這篇文章主要介紹了JPA之多對(duì)多查詢死循環(huán)嵌套問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • java實(shí)現(xiàn)發(fā)送郵箱驗(yàn)證碼

    java實(shí)現(xiàn)發(fā)送郵箱驗(yàn)證碼

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)發(fā)送郵箱驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 新版IDEA使用Spring Initializr創(chuàng)建工程的兩種方法

    新版IDEA使用Spring Initializr創(chuàng)建工程的兩種方法

    這篇文章主要介紹了新版IDEA使用Spring Initializr創(chuàng)建工程(兩種方法,官方工具和IDEA),文中通過(guò)代碼示例和圖文結(jié)合的方式給大家講解的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下
    2024-10-10

最新評(píng)論

龙里县| 琼海市| 郎溪县| 屯昌县| 宿迁市| 永平县| 杭州市| 安丘市| 应城市| 神木县| 辉南县| 泰来县| 无为县| 武定县| 平遥县| 泗洪县| 闽清县| 玉林市| 屏山县| 黔西县| 上林县| 安西县| 沙河市| 安泽县| 无极县| 海原县| 塘沽区| 玛纳斯县| 陕西省| 新巴尔虎右旗| 丰台区| 元江| 理塘县| 冷水江市| 平原县| 白沙| 武功县| 武冈市| 福州市| 桃园县| 巴中市|