2015-11-30 57 views
2

背景:在像Spring這樣的幾個Java框架中,有可能使用注入參數值調用方法。一個很好的例子是Spring Web/MVC中的控制器動作,它接收POST值並具有重定向屬性。Java中的方法參數注入是如何工作的

例子:

@RequestMapping(value = "/testform", method = RequestMethod.POST) 
public ModelAndView testform(@RequestParam(value = "postvalue") String postvalue, RedirectAttributes attributes) 
{ 
    if(postvalue.equals("Test")) 
    { 
     // Do stuff with attributes 
    } 
    return new ModelAndView("addresses"); 
} 

例如,當我想用​​類似的東西在自己的應用程序(包括可用的無彈簧) - 我結束了類似的東西(砍死一起):

Strign actionname = "mymethod"; 
Controller controller = new SampleController(); 
for(Method method : controller.getClass().getDeclaredMethods()) 
{ 
    String name = method.getName(); 
    if(name.equals(actionname)) 
    { 
     int parametercount = method.getParameterCount(); 
     if(parametercount == 0) // No parameter 
     { 
      ModelAndView view = (ModelAndView) method.invoke(controller); 
      // Do stuff 
     } 
     else if(parametercount == 1) // 1 String parameter 
     { 
      ModelAndView view = (ModelAndView) method.invoke(controller, new String("parameter1")); 
      // Do stuff 
     } 
     else if(parametercount == 2) // 2 String parameters 
     { 
      ModelAndView view = (ModelAndView) method.invoke(controller, new String("parameter1"), new String("parameter2")); 
      // Do stuff 
     } 
     else // Error 
     { 
      // Unsupported method 
     } 
     break; 
    } 
} 

問題:該解決方案只支持一個字符串作爲參數的空隙,1-參數和2參數的方法 - 沒有別的

問題: Java和Spring如何允許這樣的功能? Spring是否有適合最常用方法的大量method.invoke(...)或者是否存在對此問題更動態的解決方案?

最終的解決方案:我結束了這個(未完成)解決方案基於Seelenvirtuose答案:

else if(parametercount == 2) 
{ 
    Object[] parameters = new Object[2]; 
    parameters[0] = new String("Hello"); 
    parameters[1] = new String("world!"); 
    method.invoke(controller, parameters); 
} 
+3

請勿使用'=='比較Java中的字符串。 'if(postvalue ==「Test」)''應該是:'if(postvalue.equals(「Test」))' – Jesper

+0

另外,不需要在文字中使用'new String(...)'。只需寫''parameter1「'而不是'new String(」parameter1「)''。 – Jesper

+0

不要使用名字魔法,像Spring一樣使用註釋。這樣你就不需要依賴參數的數量和順序,只需調用'Method.getParameterAnnotations()'並使用它來確定注入哪個參數。 – biziclop

回答

4
從任何注射依賴框架

除了一般(春季特別),你似乎問如何用任意數量的參數反射地調用方法。

正如您在invoke method's signature中看到的那樣,您可以在陣列中提供所有參數。所以,你應該簡單地組裝參數數組並規定:

Object[] arguments = createArguments(parametercount); // create array of correct size 
(ModelAndView) method.invoke(controller, arguments); 

注意,那可變參數都像一個ARRY處理。哦,並且請尊重關於字符串行爲的評論。

+0

謝謝,這解決了我的問題。我總是直接用數據初始化數組(在聲明期間),但從未想過稍後設置值並將對象數組傳遞給invoke方法。 – swaechter

3

原則上Spring做同樣的事情,只是更復雜。

尤其是他們不尋找名字(至少對於很多事情),但對於註釋。您可以獲取類,方法,字段等的註釋。

他們將使用的另一件事是調用需要一個可變參數,它基本上是一個數組,因此它不是每個參數都有一個if分支,而是隻傳遞一個具有正確數量的元素的數組。

+0

的確,但有些人更喜歡-paramaters選項,所以Java編譯器會添加調試信息,並且您可以獲取參數名稱。另外vararg不是一個合適的解決方案(獲取POST值的數組操作) – dasskorpion

相關問題