简体   繁体   English

方法参数注入如何在Java中工作

[英]How does method parameter injection work in Java

Background: In several Java frameworks like Spring there is the possibility to have methods that are called with injected parameter values. 背景:在像Spring这样的几个Java框架中,有可能使用注入的参数值调用方法。 A good example is a controller action in Spring Web/MVC that receives a POST value and has a redirect attribute. 一个很好的例子是Spring Web / MVC中的一个控制器动作,它接收一个POST值并具有一个redirect属性。

Example: 例:

@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");
}

For example when I would like to use something similar in an own application (No Spring included available) - I end up with something like that (Hacked together): 例如,当我想在自己的应用程序中使用类似的东西(没有包含可用的Spring)时 - 我最终得到类似的东西(被黑客攻击):

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;
    }
}

Problem: This solution only supports void, 1-parameter and 2-parameter methods that take a string as argument - nothing else 问题:此解决方案仅支持将字符串作为参数的void,1参数和2参数方法 - 没有别的

Question: How does Java and Spring allow such a feature? 问题: Java和Spring如何允许这样的功能? Does Spring have a huge array of method.invoke(...) that are suitable for the most common methods or is there a more dynamic solution to this problem? Spring是否有大量的method.invoke(...)适用于最常用的方法,或者是否有更动态的解决方案?

Final solution: I ended up with this (unfinished) solution based on Seelenvirtuose answer: 最终解决方案:我最终得到了基于Seelenvirtuose答案的这个(未完成的)解决方案:

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

Aside from any injection dependency frameworks in general (and Spring specifically), you seem to ask how to reflectively call methods with an arbitrary number of parameters. 除了一般的注入依赖框架(特别是Spring)之外,您似乎还要问如何使用任意数量的参数反射调用方法。

As you can see in the invoke method's signature , you provide all parameters in an array . 正如您在invoke方法的签名中看到的那样,您可以在数组中提供所有参数。 So you simply should assemble an argument array and provide that: 所以你只需要组装一个参数数组并提供:

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

Note, that varargs are treated like an arry. 请注意, varargs被视为arry。 Oh, and please respect the comments about string behaviors. 哦,请尊重有关字符串行为的评论。

In principle Spring does the same thing, just more sophisticated. 原则上,Spring做同样的事情,只是更复杂。

Especially they don't look for names (at least for many things) but for annotations. 特别是他们不寻找名称(至少对很多事情而言),而是寻找注释。 You can get the annotations of classes, methods, fields and so on. 您可以获取类,方法,字段等的注释。

The other thing they'll use is that invoke takes an vararg, which is basically an array, so instead of having one if branch for each number of parameters, they pass just an array with the correct number of elements. 他们将使用的另一件事是invoke采用一个vararg,它基本上是一个数组,所以不是每个参数数量都有一个if分支,它们只传递一个具有正确数量元素的数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM