猿问

如何在 Spring Boot 2 中检索应用程序上下文

我ApplicationContextProvider定义了这个类以及MyApplication.java(运行应用程序的入口点):


package com.company.my.app;


import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

import org.springframework.stereotype.Component;



@Component

public class ApplicationContextProvider implements ApplicationContextAware {


  private ApplicationContext applicationContext;


  @Override

  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

    this.applicationContext = applicationContext;

  }


  public ApplicationContext getContext() {

    return applicationContext;

  }

}

restapi拥有包含两个类的包(Greeting只是一个保存数据的类):


package com.company.my.app.restapi;


import com.company.my.app.ApplicationContextProvider;

import io.micrometer.core.instrument.Counter;

import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.context.ApplicationContext;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;



@RestController

public class GreetingController {


  private static final Logger LOG = LoggerFactory.getLogger(GreetingController.class);


  private static final String template = "Hello, %s!";

  private final AtomicLong counter = new AtomicLong();


  @RequestMapping("/greeting")

  public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {


    ApplicationContextProvider acp = new ApplicationContextProvider();

    ApplicationContext context = acp.getContext();


    if (context == null) LOG.info("app context is NULL");


    Counter bean = context.getBean(Counter.class);

    bean.increment();


    return new Greeting(counter.incrementAndGet(),

        String.format(template, name));

  }

当我运行该应用程序并http://localhost:8081/greeting在我的浏览器中调用时,它会崩溃打印app context is NULL。如何获取应用程序上下文?我需要它来检索简单的计数器 bean。



子衿沉夜
浏览 96回答 1
1回答

ibeautiful

你不需要上下文;有更好的方法。ApplicationContextAware是许多旧版本 Spring 的产物,在许多现在的标准功能可用之前。在现代 Spring 中,如果您需要ApplicationContext,只需像注入任何其他 bean 一样注入它。但是,您几乎可以肯定不应该直接与它交互,尤其是对于getBean,应该将其替换为注入您得到的任何东西。一般来说,当你需要一个 Spring bean 时,你应该将它声明为构造函数参数。(如果你有多个构造函数,你需要用 注释一个@Autowired,但如果只有一个构造函数,Spring 足够聪明知道使用它。)如果你正在使用 Lombok,你可以使用 来@Value自动编写构造函数,并且Groovy 和 Kotlin 具有相似的功能。在您在这里展示的 Micrometer 的特定情况下,将单个指标声明为 beans 是不常见的,因为它们是旨在应用于特定代码路径的细粒度工具。(某些服务可能有 10 个单独的指标来跟踪各种可能的情况。)相反,您注入MeterRegistry并选择您需要的计数器或其他指标作为构造函数的一部分。在这里,您的控制器类应该如下所示。(我已经删除了重复项AtomicLong,但如果有特定原因需要它,您可以按照显示的那样将其添加回去。)@RestControllerpublic class GreetingController {  private static final Logger LOG = LoggerFactory.getLogger(GreetingController.class);  private static final String template = "Hello, %s!";  private final Counter counter;  public GreetingController(MeterRegistry meterRegistry) {    counter = meterRegistry.counter("my.counter");  }  @RequestMapping("/greeting")  public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {    counter.increment();    long count = (long) counter.count();    return new Greeting(count, String.format(template, name));  }}
随时随地看视频慕课网APP

相关分类

Java
我要回答