方法参数注入如何在 Java 中工作
How does method parameter injection work in Java
背景: 在像 Spring 这样的几个 Java 框架中,有可能使用注入的参数值调用方法。一个很好的例子是 Spring Web/MVC 中的控制器操作,它接收 POST 值并具有重定向属性。
示例:
@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");
}
例如,当我想在自己的应用程序中使用类似的东西时(不包含可用的 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;
}
}
问题:此解决方案仅支持将字符串作为参数的 void、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);
}
除了任何一般的注入依赖框架(特别是Spring),您似乎在问如何反射调用具有任意数量参数的方法。
如您在 invoke
method's signature 中所见,您在 数组 中提供了所有参数。所以你只需要 assemble 一个参数数组并提供:
Object[] arguments = createArguments(parametercount); // create array of correct size
(ModelAndView) method.invoke(controller, arguments);
请注意,varargs 被视为 arry。哦,请尊重关于字符串行为的评论。
原则上Spring做同样的事情,只是更复杂。
特别是他们不寻找名称(至少对于很多事情),而是寻找注释。可以获得类、方法、字段等注解
他们将使用的另一件事是 invoke 接受一个 vararg,它基本上是一个数组,因此他们没有为每个参数数量设置一个 if 分支,而是只传递一个具有正确数量元素的数组。
背景: 在像 Spring 这样的几个 Java 框架中,有可能使用注入的参数值调用方法。一个很好的例子是 Spring Web/MVC 中的控制器操作,它接收 POST 值并具有重定向属性。
示例:
@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");
}
例如,当我想在自己的应用程序中使用类似的东西时(不包含可用的 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;
}
}
问题:此解决方案仅支持将字符串作为参数的 void、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);
}
除了任何一般的注入依赖框架(特别是Spring),您似乎在问如何反射调用具有任意数量参数的方法。
如您在 invoke
method's signature 中所见,您在 数组 中提供了所有参数。所以你只需要 assemble 一个参数数组并提供:
Object[] arguments = createArguments(parametercount); // create array of correct size
(ModelAndView) method.invoke(controller, arguments);
请注意,varargs 被视为 arry。哦,请尊重关于字符串行为的评论。
原则上Spring做同样的事情,只是更复杂。
特别是他们不寻找名称(至少对于很多事情),而是寻找注释。可以获得类、方法、字段等注解
他们将使用的另一件事是 invoke 接受一个 vararg,它基本上是一个数组,因此他们没有为每个参数数量设置一个 if 分支,而是只传递一个具有正确数量元素的数组。