一尘不染

将对象的新实例注入每个请求处理程序

spring-mvc

我有很多Spring
RestControllers方法带有注释RequestMapping。我现在想将自定义对象注入这些RequestMapping方法,并为每个请求创建一个自定义实例。

我想写类似下面的东西:

@RequestMapping("/search")
public SomeReturnObject foobar(@RequestParam("query") String query, MyRequestFoo foo) {
   // ...
}

现在,我想创建一种机制,其中对该方法的每次调用(即每个请求)都将获得一个MyRequestFoo创建的新实例并将其注入该方法中。如果使用参数注释而不是按类型进行注入会更好,那么也可以(例如@MyRequestInject MyRequestFoo foo)。

我需要知道是否现在可以创建一个方法,该方法MyRequestFoo专门为该请求创建一个新实例,如下所示:

public MyRequestFoo createRequestInstanceSomehow(HttpServletRequest request) {
   // extract some values from the HttpServletRequest and create a
   // new MyRequestFoo instance from that and return it
}

是否有可能通过任何方式创建这样的机制,以便将自定义的每个请求对象注入到我的请求处理方法中?


阅读 315

收藏
2020-06-01

共1个答案

一尘不染

Spring MVC有一个参数解析器构造,可直接支持您的请求。用 @RequestMapping
注释的每个处理程序方法都将进行参数解析,其中框架将扫描处理程序参数,检查类型并实例化适当的对象。这就是注入请求,模型和许多其他类型的机制,仅通过在处理程序的方法签名中声明对象即可。

您可以编写自定义参数解析程序,以解析自定义类型并在方法中可用。程序简单三步过程

  1. 在您的情况下,创建一个POJO类 MyRequestFoo

  2. 制作解析器,例如

      public class MyRequestFooResolver implements HandlerMethodArgumentResolver {
    
        @Override
        public boolean supportsParameter(MethodParameter parameter) {
    
            return parameter.getParameterType().equals(MyRequestFoo.class);
        }
    
        @Override
        public Object resolveArgument(MethodParameter parameter, 
                                      ModelAndViewContainer mavContainer,
                                      NativeWebRequest webRequest, 
                                      WebDataBinderFactory binderFactory)
        throws Exception {
    
            return new MyRequestFoo();
        }
    }
    

3.注册解析器

 <mvc:annotation-driven>
     <mvc:argument-resolvers>
         <bean class="your.package.MyRequestFooResolver "></bean>  
     </mvc:argument-resolvers>
 </mvc:annotation-driven>

或在Java配置中

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

  @Override
  public void addArgumentResolvers(List< Handlermethodargumentresolver > argumentResolvers) {
        MyRequestFooResolver myRequestFooResolver = new MyRequestFooResolver ();
        argumentResolvers.add(myRequestFooResolver );
  }
}

比仅通过将类型添加为处理程序方法参数来使用它

@RequestMapping("/search")
public SomeReturnObject search(MyRequestFoo foo) {
   // ...
}
2020-06-01