spring 的 ApplicationContext.getBean(type) 無法擷取bean,報錯

來源:互聯網
上載者:User

標籤:現在   frame   ESS   get   rri   ted   首字母   raise   註解   

具體問題請看   https://q.cnblogs.com/q/108101/

研究了兩天: 經過上文中的排除法: 造成問題的原因是要擷取的bean 中 有被切入的方法。。

  就是可能該類會使用反射產生一個類。。

怎麼測試呢?

  想到 @Autowired  和 @Resource  這兩個註解。。

他們會通過 類型 和 名稱去找容器中對應 的 bean 。。

於是在controller 中使用 這個註解 注入 zaService; 

報錯了  : 

  

Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named ‘zaSerivce‘ is expected to be of type ‘com.mytest.context.impl.ZaSerivce‘ but was actually of type ‘com.sun.proxy.$Proxy15‘at org.springframework.beans.factory.support.DefaultListableBeanFactory.checkBeanNotOfRequiredType(DefaultListableBeanFactory.java:1510)at org.springframework.beans.factory.support.DefaultListableBeanFactory.checkBeanNotOfRequiredType(DefaultListableBeanFactory.java:1517)at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1489)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)... 67 more

  這就說明了兩個問題: 1. 為什麼 byTpe 無法擷取bean ,,因為它的類型根本就不是  com.mytest.context.impl.ZaSerivce 而是    com.sun.proxy.$Proxy15

            2.  byName 雖然可以擷取但是會發現它的類型也已經不是 ZaService 了。。 

ApplicationContext context =  ApplicationContextUtils.context;        ZaService z = (ZaService) context.getBean("zaService");java.lang.ClassCastException: com.sun.proxy.$Proxy15 cannot be cast to com.mytest.context.impl.ZaService

  

 

 

解決辦法: 1. 通過byType 擷取bean 時參數傳 介面類的class ..    不足: 只能有一個實作類別。

      2.  byName 可以正常傳參數 bean 的首字母小寫。。 但是只能轉換為介面類 

          IZaService z = (IZaService) context.getBean("zaService");

 

  而我的業務參數是  實作類別的全路徑名,所以特別適合 class.forName();  然後 byType .. 可惜用不了。。 只能退而求其次了把參數 調整為 介面的全路徑名。。但是只能有一個實作類別。。

至於為什麼被 切 的 類 在spring 容器中的 type 變了, 那可能要考慮代理反射,個人觀點是 spring 預設使用jdk 動態代理,這種方式會產生一個全新的類,比如本例的

$Proxy15, 然後通過這個代理類方法前後編入代碼,然後調用原始類的方法。。 說遠了,。。。。 

注意 : spring 還有一種代理方式: CGLIB 是不會產生新的類,那如果不產生新的類,就不會出現上述的問題了,,現在驗證下(spring 對沒有實現介面的類的代理方式是 CGLib )

我們只要把 IZaServiec 去掉就行了不要Zaserivce 實現它,試試,,日,,真的正常了。。
      
@Servicepublic class ZaService  {    @TestAnn    /*@Override*/    public void aa() {    }}@ResponseBody    @RequestMapping("/context")    public String context(){        ApplicationContext context =  ApplicationContextUtils.context;        ZaService z = (ZaService) context.getBean(ZaService.class);        System.out.println(z);        z.aa();        return "context";    }[email protected]<>>>>>>>>>>>>>>>>>>>>>>>after<><><><><>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  



 

spring 的 ApplicationContext.getBean(type) 無法擷取bean,報錯

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.