簡體   English   中英

JMH Benchmark 在 Spring(使用 maven)項目中使用 Autowired 字段獲取 NullPointerException

[英]JMH Benchmark get NullPointerException with Autowired field in Spring(with maven) project

我嘗試對我的 Spring (with maven) 項目的一些方法進行基准測試。 我需要在我的項目中的幾個字段上使用@Autowired 和@Inject。 當我運行我的項目時,它運行良好。 但是 JMH 總是使用 @Autowired/@Inject 字段獲得 NullPointerException。

public class Resources {

    private List<Migratable> resources;

    @Autowired
    public void setResources(List<Migratable> migratables) {
        this.resources = migratables;
    }

    public Collection<Migratable> getResources() {
        return resources;
    }
}

我的基准課程

@State(Scope.Thread)
public class MyBenchmark {

    @State(Scope.Thread)
    public static class BenchmarkState {

        Resources res;

        @Setup
        public void prepare() {
            res = new Resources();
        }
    }

    @Benchmark
    public void testBenchmark(BenchmarkState state, Blackhole blackhole) {
        blackhole.consume(state.res.getResources());
    }
}

當我運行我的基准測試時,它會在Resources.getResources()更具體地說是在resources獲得 NullPointerException。
它不能自動裝配 setResources()。 但是如果我運行我的項目(不包括基准測試),它工作正常。
如何在基准測試時擺脫帶有 Autowired 字段的 NullPointerException?

以下是如何運行基於 Spring 的基准測試的示例: https ://github.com/stsypanov/spring-boot-benchmark。

基本上,您需要的是將應用程序上下文的引用存儲為基准類的字段,在@Setup方法中初始化上下文並在@TearDown中關閉它。 像這樣的東西:

@State(Scope.Thread)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@BenchmarkMode(value = Mode.AverageTime)
public class ProjectionVsDtoBenchmark {

  private ManyFieldsRepository repository;

  private ConfigurableApplicationContext context;

  @Setup
  public void init() {
    context = SpringApplication.run(Application.class);
    context.registerShutdownHook();

    repository = context.getBean(ManyFieldsRepository.class);
  }

  @TearDown
  public void closeContext(){
    context.close();
  }
}

您要測量的邏輯必須封裝在 Spring 組件的一個方法中,該方法從@Benchmark注釋方法調用。 記住基准測試的一般規則以確保您的測量是正確的,例如使用Blackhole或從方法返回值來防止編譯器從 DCE。

嘗試使用

測試類上的@RunWith(SpringJUnit4ClassRunner.class) and @ContextConfiguration(locations = {...}) 這應該初始化Spring TestContext Framework並讓您自動關聯依賴項。

如果這不起作用,則必須使用以下任一方法顯式啟動Spring ApplicationContext作為@Setup帶注釋方法的一部分。

ClassPathXmlApplicationContext,FileSystemXmlApplicationContext或WebXmlApplicationContext並從該上下文解析bean:

ApplicationContext context = new ChosenApplicationContext("path_to_your_context_location");
res = context.getBean(Resources.class);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM