2016-11-14 158 views
0

我在RedisConfiguration中聲明瞭beans,例如RedisTemplate<Long, Permission>,RedisTemplate<Long, Order>。 下面的代碼顯示,Spring如何找到匹配的bean?

@Bean 
public RedisTemplate<String, Order> orderRedisTemplate(RedisConnectionFactory redisConnectionFactory) { 
    RedisTemplate<String, Order> redisTemplate = new RedisTemplate<>(); 
    configure(redisTemplate, redisConnectionFactory); 
    return redisTemplate; 
} 

@Bean 
public RedisTemplate<String, Permission> permissionRedisTemplate(RedisConnectionFactory redisConnectionFactory) { 
    RedisTemplate<String, Permission> redisTemplate = new RedisTemplate<>(); 
    configure(redisTemplate, redisConnectionFactory); 
    return redisTemplate; 
} 

默認情況下,該聲明的名稱的名稱是聲明的方法的名稱。 現在,我寫了一個測試代碼,它在TestController中聲明瞭一個帶註釋的@Autowired。 測試代碼如下:

@Autowired 
RedisTemplate<String, Permission> permissionTemplate; 

然後,我訪問到的TestController。它運行良好。 但是,我在測試中有一個問題。 Spring如何發現在RedisConfiguration中聲明的Bean並將其分配給permissionTemplate文件? 正如我們所知,Java編譯時間中的泛型類型已被刪除,因此Spring不可能通過泛型找到正確的Bean。 下一個可能性是Spring通過filedName找到了聲明的Bean。 要批准我的建議,我修改了TestController中的字段,如下所示。

@Autowired 
RedisTemplate<String, Permission> orderTemplate; 

然後,我請求了TestController。它也工作得很好。該測試表明Spring使用Generic Type來查找匹配的Bean。

Spring如何知道permissionTemplate的泛型?

+0

是有類型擦除,*但*類型的信息還保存方法簽名。 IIRC Spring依靠getter/setter方法簽名來了解屬性的類型參數並將其用於自動佈線。所以在你的TestController中,添加一個相應的getter應該可以工作。 –

+0

嗨,thx給你評論。我發佈的上一個問題是錯誤的,然後我修改了我的問題。你能花一點時間再看看我的問題嗎?真的很感謝你。 – Iconoclast

+0

同樣的答案對我來說:我相信你有屬性的getter/setter,並且Spring從getter/setter簽名中獲得泛型類型信息。 (順便說一句,我想它應該是'RedisTemplate orderTemplate;'?) –

回答

1

是的,Java泛型有類型擦除,但泛型類型信息仍然存在於字節碼中,用於很多場景,如字段,返回類型和方法參數。 Spring使用這些信息來確定泛型類型信息,從而進行bean類型匹配。

示範的通用信息在運行時是可用:

import java.lang.reflect.*; 
public class Foo { 
    private List<String> fooField; 

    public static void main(String[] args) throws Exception{ 
     for (Field f : Foo.class.getDeclaredFields()) { 
      if (f.getName().equals("fooField")) { 
       System.out.println("Generic Types " + f.getGenericType()); 
       break; 
      } 
     } 
    } 
} 

你應該看到輸出:

Generic Types java.util.List<java.lang.String> 
+0

謝謝,我真的需要再次學習java的基礎知識。 – Iconoclast

+0

歡迎光臨。儘管如此,我並不認爲它是「基本」的知識:p我個人忘記了Field還有首要類型的信息:P –