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

如何从HttpServlet访问同一个bean的实例?

尚恩
2023-03-14

我对Spring框架有点陌生。我有一个用Spring (4.2.1)编写的web应用程序。我正在尝试使用千分尺库来揭示度量标准,并将与普罗米修斯一起使用。

应用程序的相关结构如下:
-核心模块(JAR)
-webservice模块(WAR)

我创建了一个PrometheusService类,它是在核心模块中定义的bean。bean中定义的是PrometheusMeterRegistry计数器

@Service
public class PrometheusService {

    private static PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
    private static Counter newAssetCounter = Counter
            .builder("new_asset_counter")
            .description("count of created assets")
            .tags("region", "na")
            .register(registry);

    public PrometheusService() {
        new JvmMemoryMetrics().bindTo(registry);
        new DiskSpaceMetrics(new File("/")).bindTo(registry);
        new ProcessorMetrics().bindTo(registry);
        new UptimeMetrics().bindTo(registry);
    }

    public static PrometheusMeterRegistry getRegistry() {
        return registry;
    }

    public Counter getNewAssetCounter() {
        return this.newAssetCounter;
    }

}

我创建了指标资源,它是一个公开 /Metrics endpoint的 Http 服务器。当试图@Autowire普罗米修斯服务豆时,它在这里总是空的。快速搜索告诉我,网络服务器不是由斯普林管理的。如果我想@Autowire,我需要添加这样的东西:

< code > springbean autowiringsupport . processinjectionbasedoncurrentcontext(webApplicationContext);

现在,我能够在Servlet中使用<code>@Autowire</code>PrometheusService bean。

bean中定义的计数器在核心模块内递增。MetricsResourcesdoGet方法写入存储在PrometheusMeter注册表中的指标。

@WebServlet("/metrics")
public class MetricsResource extends HttpServlet  {

    private PrometheusService promService; // @Autowired
    private PrometheusMeterRegistry registry;

    @Override
    public void init() throws ServletException {
        super.init();

//        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(webApplicationContext);

//        promService = (PrometheusService) getServletContext().getAttribute("prometheusService");

//        WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
//        AutowireCapableBeanFactory ctx = context.getAutowireCapableBeanFactory();
//        ctx.autowireBean(this);
    }

    @Override
    protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
        resp.setStatus(HttpServletResponse.SC_OK);
        resp.setContentType(TextFormat.CONTENT_TYPE_004);

        registry = promService.getRegistry();

        Writer writer = resp.getWriter();
        try {
            registry.scrape(writer);
            writer.flush();
        } finally {
            writer.close();
        }
    }
}

但问题是,计数器的值在/metricsendpoint处始终为0。

不管它是@Autowired还是我手动尝试获取bean。

这怎么可能?我的PrometheusService bean是单例的。甚至PrometheusMeterRegistry和计数器都被标记为static,那么为什么我在servlet中得到一个不同的对象呢?经过进一步的搜索,我发现Spring将为每个容器创建一个singleton bean。所以我假设这里有两个容器或上下文。一个主应用程序上下文和一个servlet上下文。

我尝试了一些事情:
使用ServiceLocator类实现PrometheusService实现ApplicationContextAware
实现ApplicationContextA并返回bean
将上下文参数添加到web。xml
在应用程序上下文中使用ServletContextAttributeExporter。xml
使用WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext())

我继续获得该对象的新实例。我想做的就是能够使用千分尺创建和公开自定义指标。我的方法有缺陷吗?如何从我的HttpServlet中访问正确的bean?

Spring依赖注入到其他实例
http://senthadev.com/sharing-spring-container-between-modules-in-a-web-application.html
Spring依赖注入到其他实例<br>ApplicationContext和ServletContext

共有1个答案

公孙慎之
2023-03-14

请尝试< code > processInjectionBasedOnServletContext(Object target,servlet context servlet context)。

 类似资料:
  • 我得写一个石英调度器来在Spring运行一个作业。我还需要添加另一个函数来暂停同一个作业。此代码存在于单个独立批处理中。 触发这两个功能:1。开始工作2。暂停作业我已经用main()编写了两个类来执行。 问题是当我触发pauseJobs的main()时,它会启动不同的应用程序上下文,而不是使用相同的应用程序上下文。 > 用于Application Context初始化的Singleton类 类开始

  • 例如,我有两个心率监视器与我的平板电脑配对。我正在使用这样的代码来获取HRM设备列表: 然后,我在GUI中显示一个列表框,其中包含从设备[I]获取的设备名称。名称例如,我选择索引为0的设备。然后我可以访问it人力资源服务和人力资源管理特征: 除了心率,我还需要电池状态。如何访问同一(已选择)设备的电池服务?

  • 问题内容: 这是我的工作方式 然后在 假设用户名是。然后,如果单击,将设置为Peter的用户对象,然后重定向到配置文件页面,该页面现在从中呈现信息。我只想使用创建相同的效果,因此想到了GET请求。所以我这样做 然后该方法就返回 剩下的就是创建一个servlet,捕获该,查询数据库以获取设置为重定向的对象。这是我的servlet 现在我有了,如何访问会话bean来查询数据库中的,然后访问受管Bean

  • 问题内容: 我们正在做一个MySQL的小型基准测试,我们希望了解它对数据的性能。 该测试的一部分是查看当多个并发线程对服务器执行各种查询时,服务器如何工作。 在MySQL文档(5.0)是不是多线程的客户真的清楚。我应该指出,我确实针对线程安全库()进行了链接 我正在使用准备好的语句,并且同时执行读取(SELECT)和写入(UPDATE,INSERT,DELETE)操作。 我应该为每个线程打开一个连

  • 我是java新手,我不知道如何从另一个类访问变量 我正在尝试编写一个代码来发送带有未存储在本地的附件的邮件。我想访问SendMail类中ExcelFile类中编写的变量 如何在另一个类中访问excelFileAsByte并发送邮件而不将其存储在本地。我可以使用addBodyPart和ByteArrayResource将文件添加为附件吗。

  • 带有同伴对象的简单示例类 值测试可以通过访问,但如何从MyClass的实例访问?如果我有,那么我如何从sample访问测试?不正确....有没有办法? Java,C++,python等都有很简单的解决方案...(我将为每个有帮助的is提供代码示例),我认为kotlin会有一个比使用Java更好的解决方案。 对于在没有对象实例(如工厂)的情况下访问类属性,kotlin companion objec