Spring Boot-自动配置包含AutoWired依赖项的类



我正在开发一个具有可重用逻辑的通用java库,以与一些AWS服务交互,这些服务将被几个消费者应用程序使用。由于这里概述的原因,以及Spring Boot似乎为SQS集成等提供了许多无样板的代码,我决定将这个公共库实现为具有自动配置的自定义Spring Boot启动器。

我对Spring框架也完全陌生,因此遇到了一个问题,即我的自动配置类的实例变量没有通过AutoWired注释进行初始化。

为了更好地解释这一点,这里是我的常见依赖项的一个非常简化的版本。

CommonCore.java

@Component
public class CommonCore { 
@AutoWired
ReadProperties readProperties;
@AutoWired
SqsListener sqsListener; // this will be based on spring-cloud-starter-aws-messaging 
public CommonCore() {
Properties props = readProperties.loadCoreProperties();
//initialize stuff
}
processEvents(){
// starts processing events from a kinesis stream.
}
}

ReadProperties.java

@Component
public class ReadProperties {
@Value("${some.property.from.application.properties}")
private String someProperty;
public Properties loadCoreProperties() {
Properties properties = new Properties();
properties.setProperty("some.property", someProperty);

return properties;
}
}

CoreAutoConfiguration.java

@Configuration
public class CommonCoreAutoConfiguration {
@Bean
public CommonCore getCommonCore() {  
return new CommonCore();
}
}

常见的依赖关系将被其他应用程序使用,如

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class SampleConsumerApp implements ApplicationRunner {
@Autowired
CommonCore commonCore;
public SampleConsumerApp() {
}
public static void main(String[] args) {
SpringApplication.run(SampleConsumerApp.class, args);
}
@Override
public void run(ApplicationArguments args) {
try {
commonCore.processEvents();
} catch (Exception e) {
e.printStackTrace();
}
}
}

正如我提到的,我遇到的主要问题是CommonCore实例中的AutoWired对象没有按预期进行初始化。然而,我认为实际问题的根源更为深刻;但由于我对Spring框架缺乏了解,我发现自己很难调试它。

我希望能在这几点上提供一些建议

  1. 这种开发自定义启动器的方法对我的用例有意义吗
  2. AutoWired依赖项没有用这种方法初始化的原因是什么

猜测,但我认为这是因为事物的构造顺序。我说的是这门课:

@Component
public class CommonCore { 
@AutoWired
ReadProperties readProperties;
@AutoWired
SqsListener sqsListener; // this will be based on spring-cloud-starter-aws-messaging 
public CommonCore() {
Properties props = readProperties.loadCoreProperties();
//initialize stuff
}
processEvents(){
// starts processing events from a kinesis stream.
}
}

您正试图在构造函数中使用Spring注入的组件,但在Spring执行其@Autowire魔术之前,构造函数已被调用。

因此,一种选择是自动连线作为构造函数参数

类似的东西(未经测试(:

@Component
public class CommonCore { 
private final ReadProperties readProperties;
private final SqsListener sqsListener; // this will be based on spring-cloud-starter-aws-messaging 
@AutoWired 
public CommonCore(SqsListener sqsListener, ReadProperties readProperties) {
this.readProperties = readPropertis;
this.sqsListener = sqsListener;
Properties props = readProperties.loadCoreProperties();
//initialize stuff
}
processEvents(){
// starts processing events from a kinesis stream.
}
}

旁注:我更喜欢通过构造函数参数始终使用依赖项注入,只要可能。这也使得单元测试在没有任何Spring特定测试库的情况下变得更加容易。

最新更新