參考:http://tutorials.jenkov.com/java-reflection/classes.html#superclass
需求:
最近開始研究Spring對於他使用XML可以做DI(Dependency injection)的方式產生了興趣,其中產生bean之後的constructor parameter居然也可以使用XML直接設定而不需要在application中指定id名稱的特性...想來想去也只有Reflection可以辦到了,因此有了以下的小實驗:
我們需要達到兩項目標:
- 取得指定Class的Super Class
- 取得指定Class的implement Interface(s)
直接看Code:
我們定義了兩個Interface:ISuperA、ISuperB
接下來定義implement:
我們定義了兩個Interface:ISuperA、ISuperB
public interface ISuperA { }
public interface ISuperB { }
接下來定義implement:
public class ImplementClass implements ISuperA, ISuperB { }
呼叫看結果:
public static void main(String[] args) { Class superclass = ImplementClass.class.getSuperclass(); Class[] interfaces = ImplementClass.class.getInterfaces(); System.out.println("superclass:"+superclass.getName()); System.out.println("interfaces:"); for(Class interface1 : interfaces) System.out.print("\t"+interface1.getName()); }
結果:
superclass:java.lang.Object interfaces: ISuperA ISuperB
補充說明,推測Spring的用法:
下面的Code來自Spring in Action 3rd - Listing 1.4、1.6、1.7:
package com.springinaction.knights; public classBraveKnightimplementsKnight{ privateQuestquest; public BraveKnight(Questquest){ this.quest=quest; } public voidembarkOnQuest()throwsQuestException{ quest.embark(); } }
XML設定:
Spring中呼叫方式如下:
package com.springinaction.knights; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public classKnightMain{ public staticvoidmain(String[]args){ ApplicationContextcontext = new ClassPathXmlApplicationContext("knights.xml"); Knightknight=(Knight)context.getBean("knight"); knight.embarkOnQuest(); } }
依照上述呼叫的Code我們可以看到,指定了XML中的"knight" create...ok這沒甚麼問題,"knight"直接對應到XML的bean id="knight",然而有趣的事情在於,需create的BraveKnight並非是使用default constructor直接建立,是有帶參數的!然而在上述呼叫中卻沒有看到指定bean id="quest"的部分。僅僅是在bean中設定了<constructor-arg ref="quest"/>就對應的到....而quest代表的並非Type型別。
因此如果按照上述的實驗,推測是先取得id="quest"的"com.springinaction.knights.SlayDragonQuest",接者取得"com.springinaction.knights.BraveKnight"中的Constructor,由Reflection機制可以取得各種Constructor的參數型別,只要能找到"一個參數",這裡我們找到的為public BraveKnight(Questquest),因此只要SlayDragonQues符合以下條件之一,那麼XML的指定條件就可成立:
- SlayDragonQues的Type為Questquest
- Questquest為SlayDragonQuest的super class
- Questquest為Interface且被SlayDragonQuest implement
最後答案是3(未列出Questquest Code),因此XML設定正確,可以被順利creation :)
沒有留言:
張貼留言