如何在 Spring 启动独立应用程序中正确使用@Autowired



我最近学到了很多关于 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;
}

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

任何帮助将不胜感激。

谢谢!

我想出了我的问题,这是一个非常愚蠢的问题。 首先,我没有用@Component注释我的主类,所以Spring从来没有费心在其中注入依赖关系。 其次,我没有意识到用@PostContruct注释的方法会在构造函数运行后自行运行,而无需显式调用!

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

你通常不必使用构造函数 + @Autorwired,你可以直接在字段上使用自动连线,Spring 会为你填充依赖项:

@Component
public class MDHIS_Service {
@Autowired
private GlobalParamService globalParamService;
}

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

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

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

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

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

编辑:我会尝试用一个例子来澄清一下...各种服务的初始化代码实际上做了什么?

也许它设置了依赖项。然后只需自动连接它们:

@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 的主服务所做的,而不是弄乱构造函数来设置这些值。

相关内容

  • 没有找到相关文章

最新更新