当前位置: 首页 > 知识库问答 >
问题:

从Java8函数创建请求范围bean

傅志用
2023-03-14
@Configuration
public class RequestConfig {

    @Bean
    public Function<? extends BaseRequest, RequestWrapper<? extends BaseRequest, ? extends BaseResponse>> requestWrapperFactory() {
        return request -> requestWrapper(request);
    }

    @Bean
    @RequestScope
    public RequestWrapper<? extends BaseRequest, ? extends BaseResponse> requestWrapper(
            BaseRequest request) {
        RequestWrapper<?, ?> requestWrapper = new RequestWrapper<BaseRequest, BaseResponse>(request);
        return requestWrapper;
    }
}
@RestController
public class CheckRequestController {

    private final RequestService<CheckRequest, CheckResponse> checkRequestServiceImpl;

    @Autowired
    private Function<CheckRequest, RequestWrapper<CheckRequest, CheckResponse>> requestWrapperFactory;

    public CheckRequestController(
            RequestService<CheckRequest, CheckResponse> checkRequestServiceImpl) {
        super();
        this.checkRequestServiceImpl = checkRequestServiceImpl;
    }

    @PostMapping(value = "/check", consumes = { MediaType.TEXT_XML_VALUE,
            MediaType.MULTIPART_FORM_DATA_VALUE }, produces = MediaType.TEXT_XML_VALUE)
    public ResponseEntity<CheckResponse> checkRequest(
            @RequestBody(required = true) CheckRequest checkRequest) {

        RequestWrapper<CheckRequest, CheckResponse> requestWrapper = requestWrapperFactory
                .apply(checkRequest);
        checkRequestServiceImpl.getResponse(requestWrapper);

        return new ResponseEntity<CheckResponse>(requestWrapper.getResponse(),
                HttpStatus.OK);
    }
}
@RestController
public class CancelRequestController {

private final RequestService<CancelRequest, CancelResponse> cancelRequestServiceImpl;

@Autowired
private Function<CancelRequest, RequestWrapper<CancelRequest, CancelResponse>> requestWrapperFactory;

public CancelRequestController(
        RequestService<CancelRequest, CancelResponse> cancelRequestServiceImpl) {
    super();
    this.cancelRequestServiceImpl = cancelRequestServiceImpl;
}

@PostMapping(value = "/cancel", consumes = { MediaType.TEXT_XML_VALUE,
        MediaType.MULTIPART_FORM_DATA_VALUE }, produces = MediaType.TEXT_XML_VALUE)
public ResponseEntity<CancelResponse> CancelRequest(
        @RequestBody(required = true) CancelRequest cancelRequest) {
    RequestWrapper<CancelRequest, CancelResponse> requestWrapper = requestWrapperFactory
            .apply(cancelRequest);
    cancelRequestServiceImpl.getResponse(requestWrapper);
    return new ResponseEntity<CancelResponse>(requestWrapper.getResponse(),
            HttpStatus.OK);
}
}
  Field requestWrapperFactory in CheckRequestController required a bean of type 'java.util.Function' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'java.util.Function' in your configuration.

共有1个答案

谭京
2023-03-14

您引用的答案有所不同:它在声明的bean和注入的bean中使用完全相同的泛型类型:

@Bean
public Function<String, Thing> thingFactory() {
    return name -> thing(name); // or this::thing
} 

和:

@Autowired
private Function<String, Thing> thingFactory;

使用泛型类型有问题吗?我做错了什么?

Function<CheckRequest, RequestWrapper<CheckRequest, CheckResponse>> requestWrapperFactory;
Function<? extends BaseRequest, RequestWrapper<? extends BaseRequest, ? extends BaseResponse>>
@Bean
public Function<? extends BaseRequest, RequestWrapper<? extends BaseRequest, ? extends BaseResponse>> requestWrapperFactory() {
    return request -> requestWrapper(request);
}

编辑后:

我更新了第一部分以与您的更改保持一致。

现在,您的要求是声明一个函数,该函数向客户机返回具有客户机指定的泛型类型的原型bean。
这是可能的。但是为了使它简洁,您不应该使用两个bean:一个用于工厂(单例),另一个用于创建RequestWrapper对象(原型)。
由于工厂bean不允许客户机指定泛型类型,您将不得不执行不希望的uncasts。
还应该用@scope(value=configurableBeanFactory.scope_prototype)替换@requestScope,因为请求作用域bean不允许像配置类中的单例和原型bean那样可配置。
例如,使用参数或通配符不能很好

因此,其思想是声明一个原型bean,返回的泛型类型取决于参数和目标。
关于RequestConfig,现在最好将其命名为RequestFactory,因为这是它的角色。

@Configuration
public class RequestFactory {

    @Bean
    @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public <T extends BaseRequest, U extends BaseResponse> RequestWrapper<T, U> requestWrapper(
            T request) {
        RequestWrapper<T, U> requestWrapper = new RequestWrapper<>(request);
        return requestWrapper;
    }

}

在控制器中插入@configurationbeanRequestFactory:

private RequestFactory requestFactory; // Change

public CheckRequestController(
        RequestService<CheckRequest, CheckResponse> checkRequestServiceImpl,
        RequestConfig requestConfig) {
    this.checkRequestServiceImpl = checkRequestServiceImpl;
    this.requestFactory = requestFactory; // Change
}

现在,只要需要,就可以用所需的RequestWrapper注入原型bean:

@PostMapping(value = "/cancel", consumes = { MediaType.TEXT_XML_VALUE,
        MediaType.MULTIPART_FORM_DATA_VALUE }, produces = MediaType.TEXT_XML_VALUE)
public ResponseEntity<CancelResponse> CancelRequest(
        @RequestBody(required = true) CancelRequest cancelRequest) {
    RequestWrapper<CheckRequest, CheckResponse> requestWrapper = 
               requestFactory.requestWrapper(cancelRequest);
     //...
    return new ResponseEntity<CancelResponse>(requestWrapper.getResponse(),
            HttpStatus.OK);
}
 类似资料:
  • 问题内容: 如果我有一个变量,如何将数字1-50放入数组中? 问题答案: 这可以通过使用简单的for循环来解决:

  • 无论 Struts2 还是 Spring,都提供了一种控制器: 每次请求,创建实例,使用后即抛弃。 这样的控制器的好处就是可以放心的吧 request 和 response 对象放心的存成它的私有 属性,反正使用一次后就丢掉了。 在 Nutz.Mvc,所谓控制器,实际上就是 Module,默认的,所有的模块都是整个应用程序唯一的, 除非你在 Ioc 配置文件里另有说明。 那么 Nutz 可以做到每

  • 本文向大家介绍dart函数范围,包括了dart函数范围的使用技巧和注意事项,需要的朋友参考一下 示例 Dart函数也可以匿名声明或嵌套声明。例如,要创建嵌套功能,只需在现有功能块中打开一个新功能块 该函数innerFunction现在可以在内部使用,并且只能在内部使用outerFunction。没有其他任何功能可以访问它。 Dart中的函数也可以匿名声明,通常用作函数参数。一个常见的例子是对象so

  • 问题内容: 到目前为止,在创建AJAX请求时,我已将其发布到单独的PHP文件中。是否可以创建一个调用PHP函数而不是发布到单独页面的jQuery AJAX请求? 如果您可以给我发送任何示例或文档,那就太好了。 问题答案: AJAX请求会调用一个URL(发出一个HTTP请求), 而不是一个文件 ,在大多数情况下,URL会由服务器转换为指向文件(或您的情况下的php脚本),但是从HTTP请求到所收到的

  • 问题内容: 此代码有效: 这两个测试用例基本相同。但是用这样的数组构造一个字符串很麻烦,而且您无法获得静态分析。所以我当时想做的是这样的: 其中孤立的是一个类似于以下内容的辅助函数: 最大的问题是Function.prototype.toString()给您整个功能。有谁知道从函数的字符串表示形式获取函数体的好方法? 更新:PRoberts在问这是什么目的,目的很简单: 问题答案: 我写了一个版本

  • 我想在我的web应用程序中使用Spring事件与我的bean“说话”。 例如,fired事件的bean如下所示: 所以,我的问题是: 事件侦听器是作用域请求是否可能?而如何做到这一点呢? 谢谢