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

如何在spring boot独立应用程序中正确使用@Autowired

聂鹏云
2023-03-14

最近我学到了很多关于Spring的知识,我想我可能会误解的一件事是@Autowired注释,尤其是在构造函数中使用它时。你看,我正在开发的应用程序是一个服务,所以基本上所有东西都是在构造函数中初始化的。唯一实际发生的用户驱动事件是重启服务某些模块的按钮。这是我的主要方法:

ConfigurableApplicationContext ctx = new SpringApplicationBuilder(MDHIS_Service.class)
        .headless(false).web(false).run(args);
    java.awt.EventQueue.invokeLater(() -> 
    {
        MDHIS_Service frame = ctx.getBean(MDHIS_Service.class);
        frame.setSize(1024, 768);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    });

这是我的主类的构造函数,基本上所有事情都发生在这里。我省略了对初始化每个模块的方法的调用,以缩短它:

@Autowired
public MDHIS_Service(GlobalParamService globalParamService, LogEntryService logentryService, InterfaceService interfaceService, 
        ConnectionService connectionService, OutboundMessageService outboundMessageService, OutboundMessageHistoryService outboundMessageHistoryService, 
        InboundMessageService inboundMessageService, FacilityService facilityService, ModuleStatusService moduleStatusService,
        SequenceService sequenceService) 
{
    this.globalParamService = globalParamService;
    this.logEntryService = logentryService;
    this.interfaceService = interfaceService;
    this.connectionService = connectionService;
    this.outboundMessageService = outboundMessageService;
    this.outboundMessageHistoryService = outboundMessageHistoryService;
    this.inboundMessageService = inboundMessageService;
    this.facilityService = facilityService;
    this.moduleStatusService = moduleStatusService;
    this.sequenceService = sequenceService;
}

我的主类为每个服务都有一个私有的final全局变量。每个模块都是一个单独的线程,我发现自己必须将这些变量传递给每个模块的构造函数,后者将这些变量存储到自己的私有最终变量中。我现在所用的方法@Autowired几乎没有用,因为我必须传递实例。有没有更好的方法来使用@Autowired?这个服务被用作一个大型web应用程序的后端,我发现自己更好地利用了其中的注释。我在这个主题上做了很多研究,并尝试了@postcontuct注释,但我得到的只是空服务。

任何帮助都将不胜感激。

谢谢

共有2个答案

羊舌赞
2023-03-14

您通常不必使用构造函数@Autorwire,您可以直接在字段上使用autow的,Spring将为您填充依赖项:

@Component
public class MDHIS_Service {

@Autowired
private GlobalParamService globalParamService;

}

重要的是要理解,要让spring工作,必须让它为您创建对象,而不是显式地调用构造函数。然后,它将根据需要填充依赖项。这是通过将服务声明为组件来实现的(例如使用@组件注释),并且从不自己创建服务,而是通过依赖注入来获取它们。

您开始使用的第一个对象必须由spring创建并由应用程序上下文返回。

作为交换,您获得的是您不必明确地转发所有内容。离应用程序根目录相当远的子子服务可以依赖于它具有可见性的任何内容,而无需一直转发引用。

我建议看一看spring参考文档,它非常详细和完整:

https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#spring-核心

编辑:我将试着用一个例子来澄清一下。。。各种服务的init代码实际上是做什么的?

也许它设置了依赖项。然后只需自动连线即可:

@Component 
MySubService {

@Autowired MySubSubService mySubSubService;

}

也许它比设置字段做更多的事情,这样您就可以在上面添加一个init方法来完成这项工作,并且这个init方法最终可以调用其他服务。

@Component 
MySubService {

@Autowired MySubSubService mySubSubService;

@PostConstruct
public void init() {
//Init code that may use mySubSubService.
}
}

您不必自己声明构造函数和转发依赖项,sprint会为您做到这一点。

唯一有问题的情况是,如果最终需要一些不依赖于init方法的参数。但即使在这种情况下,也可以从主代码中执行。这实际上是主服务调用各种setter所做的,而不是与构造函数一起设置这些值。

罗昕
2023-03-14

我发现了我的问题,这是一个相当愚蠢的问题。首先,我没有用@Component注释我的主类,所以Spring从来没有费心在其中注入依赖项。其次,我没有意识到用@PostContruct注释的方法会在构造函数运行后自行运行,而无需明确调用

我将我所有的初始化代码移动到一个用@PostConstruct注释的init方法,并用@Component注释我的主类,现在一切正常!

 类似资料:
  • 问题内容: 我正在寻找在 独立的(桌面/秋千)* 应用程序中使用 Spring的 示例或教程,我进行了很多搜索,但找不到有用的东西,所有示例和教程均适用于Web应用程序,请告知。 * 问题答案: 使用maven创建独立应用程序,如下所示: 使用Maven创建独立的应用程序 将applicationContext放在类路径中,并按如下所示将其加载到主类中: 在此处查看全文: http://www.d

  • 现在假设我们想要使用 Spark API 写一个独立的应用程序。我们将通过使用 Scala(用 SBT),Java(用 Maven) 和 Python 写一个简单的应用程序来学习。 我们用 Scala 创建一个非常简单的 Spark 应用程序。如此简单,事实上它的名字叫 SimpleApp.scala: /* SimpleApp.scala */ import org.apache.spark.S

  • 我有Kafka Streams java应用程序启动并运行。我试图使用KSQL创建简单的查询,并使用Kafka流来实现复杂的解决方案。我希望将KSQL和Kafka流作为Java应用程序运行。 我打算通过https://github.com/confluentinc/ksql/blob/master/ksqldb-examples/src/main/java/io/confluent/ksql/em

  • 问题内容: 我正在考虑开发由两部分组成的桌面应用程序: 用户界面(例如Java应用) 后端Node.js服务器 2个部分通过插座连接。不要问为什么我知道这很奇怪。 我将希望能够为客户提供带有安装程序的应用程序。我不希望用户必须自己安装Node.js。 有没有一种方法可以独立安装Node.js服务器,即无需在系统上全局安装Node.js。 对于任何(Windows,Linux,Mac OS X …)