Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java micronaut@RequestScope-不为每个传入http请求创建bean_Java_Micronaut_Requestcontext_Requestscope_Micronaut Rest - Fatal编程技术网

Java micronaut@RequestScope-不为每个传入http请求创建bean

Java micronaut@RequestScope-不为每个传入http请求创建bean,java,micronaut,requestcontext,requestscope,micronaut-rest,Java,Micronaut,Requestcontext,Requestscope,Micronaut Rest,我有一个类,下面的类是RequestScope bean: @RequestScope class RequestContext { private String requestId; private String traceId; private String authorisedId; private String routeName; // few more fields @Inject RequestContext(SecurityConte

我有一个类,下面的类是RequestScope bean:

@RequestScope
class RequestContext {

  private String requestId;
  private String traceId; 
  private String authorisedId; 
  private String routeName; 
    
  // few more fields 

  @Inject RequestContext(SecurityContext securityContext) {
        this.requestId = UUID.randomUUID().toString();
        if(securityService.getAuthentication().isPresent()){
          this.authorisedId = (securityService
                              .getAuthentication().get()).getUserId().toString();
    }
  }
  
  /* to be updated in controller method interceptors */ 
  public void updateRouteName(String name){
      this.routeName = name; 
  }
其思想是让一个包含REST请求级别自定义数据的对象可以在整个应用程序中访问,其范围显然应该在当前请求中。这可以用来表示。。日志记录-每当开发人员记录应用程序中的任何内容时,一些请求元数据就会随之出现

我不清楚@RequestScope bean到底是什么:

从它的定义来看——我的假设是,它是为每个新的http请求创建的,并且在该请求的生命周期中共享相同的实例

Micronaut何时建造?它是不变的吗

在多个请求中,我可以看到相同的请求ID(每个请求都需要新的UUID)

它是@RequestScope bean的正确用例吗

Micronaut何时建造

第一次需要bean时,在请求处理期间创建
@RequestScope
bean

它是不变的吗

可能是。在编写类时,您可以决定bean是否是可变的。正如在您的示例中所写,
RequestContext
是可变的。如果删除
updateRouteName
方法,该bean将是不可变的

它是@RequestScope bean的正确用例吗

我不这么认为,但这确实是一个基于意见的问题

编辑:基于下面添加的评论

请参阅上的项目


如果将请求范围的bean注入到单例bean中,则这可能不起作用。在这种情况下,您需要向bean注入Provider@CyrilG. 谢谢你的回复。您能让我进一步了解请求范围的bean是何时第一次创建的吗?试图将提供程序注入到单例bean中,但失败了,出现了一个ununiquebeanexception:找到了多个可能的bean候选者-它们究竟是在什么时候创建的?@cyrig。不确定那是什么错误,似乎已经清除了。但是随着提供程序的注入,每次调用Provider.get()时,它都会创建一个新的RequestContext实例,而不是请求作用域的目的感谢响应。关于不变性,正如您所指出的,我理解编写的类是可变的,但我的问题是,一旦bean在第一次需要时被构造,它似乎就不会在请求范围内的其他地方注入变异对象(updateRouteName)。另外,如何将为新请求创建的实例注入单例bean?“如何将为新请求创建的实例注入单例bean”-所有常用的注入方法word(构造函数、属性或字段)。是的,但是当注入单例bean时,它在整个应用程序生命周期中保留对请求作用域bean的相同引用(当然,因为容器bean本身就是单例的)。因此,它可能需要一个被注入到单例容器bean中的请求范围bean的代理,并且该代理应该能够对当前请求的请求范围bean进行操作。虽然“是的,但是当注入到一个单例bean中时,它在整个应用程序生命周期中保留对请求范围bean的相同引用”,但我不确定如何实现这一点——我认为这是不正确的。“t也许应该为注入到单例容器bean中的请求范围bean创建一个代理,并且该代理应该能够对当前请求的请求范围bean进行操作。”-这就是发生的情况。请参阅上的项目。在的测试表明请求作用域正在工作。
package rscope;

import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;

@Controller("/")
public class DemoController {

    private final DemoBean demoBean;

    public DemoController(DemoBean demoBean) {
        this.demoBean = demoBean;
    }

    @Get("/doit")
    public String doit() {
        return String.format("Bean identity: %d", demoBean.getBeanIdentity());
    }
}
package rscope;

import io.micronaut.runtime.http.scope.RequestScope;

@RequestScope
public class DemoBean {
    public DemoBean() {
    }

    public int getBeanIdentity() {
        return System.identityHashCode(this);
    }
}
package rscope;

import io.micronaut.http.client.RxHttpClient;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.test.annotation.MicronautTest;
import org.junit.jupiter.api.Test;

import javax.inject.Inject;

import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

@MicronautTest
public class DemoControllerTest {

    @Inject
    @Client("/")
    RxHttpClient client;

    @Test
    public void testIndex() throws Exception {
        // these will contain the identity of the the DemoBean used to handle these requests
        String firstResponse = client.toBlocking().retrieve("/doit");
        String secondResponse = client.toBlocking().retrieve("/doit");

        assertTrue(firstResponse.matches("^Bean identity: \\d*$"));
        assertTrue(secondResponse.matches("^Bean identity: \\d*$"));

        // if you modify DemoBean to be @Singleton instead of
        // @RequestScope, this will fail because the same instance
        // will be used for both requests
        assertNotEquals(firstResponse, secondResponse);
    }
}