为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

子衿沉夜 2023-02-23 18:08:50
我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;@Componentpublic 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;@RestControllerpublic 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。
查看完整描述

1 回答

?
ibeautiful

TA贡献1993条经验 获得超5个赞

你不需要上下文;有更好的方法。

ApplicationContextAware是许多旧版本 Spring 的产物,在许多现在的标准功能可用之前。在现代 Spring 中,如果您需要ApplicationContext,只需像注入任何其他 bean 一样注入它。但是,您几乎可以肯定不应该直接与它交互,尤其是对于getBean,应该将其替换为注入您得到的任何东西。


一般来说,当你需要一个 Spring bean 时,你应该将它声明为构造函数参数。(如果你有多个构造函数,你需要用 注释一个@Autowired,但如果只有一个构造函数,Spring 足够聪明知道使用它。)如果你正在使用 Lombok,你可以使用 来@Value自动编写构造函数,并且Groovy 和 Kotlin 具有相似的功能。


在您在这里展示的 Micrometer 的特定情况下,将单个指标声明为 beans 是不常见的,因为它们是旨在应用于特定代码路径的细粒度工具。(某些服务可能有 10 个单独的指标来跟踪各种可能的情况。)相反,您注入MeterRegistry并选择您需要的计数器或其他指标作为构造函数的一部分。在这里,您的控制器类应该如下所示。(我已经删除了重复项AtomicLong,但如果有特定原因需要它,您可以按照显示的那样将其添加回去。)


@RestController

public 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));

  }

}


查看完整回答
反对 回复 2023-02-23
  • 1 回答
  • 0 关注
  • 95 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信