【发布时间】:2019-08-23 13:38:20
【问题描述】:
我正在使用 Spring Cloud 函数 AWS Adapter SpringBootRequestHandler 实现 AWS lambda 函数创建处理程序。调用了GenericApplicationContext中注册的功能bean,但是组件类的自动装配给出了NullPointer Exception。
我已经在 Spring Application 中尝试使用 @ComponentScan 作为基础包。
应用类:
@Slf4j
@SpringBootApplication
@ComponentScan({ "com.poc.evthub" })
@EnableConfigurationProperties(EventHubProperties.class)
public class EventHubServerlessApplication implements ApplicationContextInitializer<GenericApplicationContext> {
public EventHubServerlessApplication() {
}
public static void main(String[] args) throws Exception {
FunctionalSpringApplication.run(EventHubServerlessApplication.class, args);
}
@Bean
public KinesisEventFunction ingestEvents() {
return new KinesisEventFunction();
}
@Override
public void initialize(GenericApplicationContext context) {
log.debug("======== initialize ========");
context.registerBean("ingestEvents", FunctionRegistration.class,
() -> new FunctionRegistration<Function<KinesisEvent, ApiResponse>>(ingestEvents())
.type(FunctionType.from(KinesisEvent.class).to(ApiResponse.class).getType()));
}
}
处理程序:
public class KinesisEventHandler extends SpringBootRequestHandler<KinesisEvent, ApiResponse> {
}
功能豆:
package com.poc.evthub.function;
import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
import com.poc.evthub.beans.ApiResponse;
import com.poc.evthub.constant.Constants;
import com.poc.evthub.service.IngestionServiceFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.function.Function;
@Slf4j
@Component
public class KinesisEventFunction implements Function<KinesisEvent, ApiResponse> {
private Context context = null;
@Autowired
private IngestionServiceFactory ingestionServiceFactory;
@Autowired
@Qualifier("targetExecutionContext")
public void setContext(Context context) {
log.info("Context: {}", context);
this.context = context;
}
@Override
public ApiResponse apply(final KinesisEvent kinesisEvent) {
log.info("KinesisEventFunction apply called...");
String sourceDomain = System.getenv(Constants.SYSENV.SOURCE_DOMAIN);
log.info("Source Domain = {}", sourceDomain);
if(null == kinesisEvent || null == kinesisEvent.getRecords()) {
log.error("Event contains no data. {}", System.lineSeparator());
//TODO build response NOT FOUND
return null;
}
else
log.info("Received {} records from {}. {}",
kinesisEvent.getRecords().size(),
kinesisEvent.getRecords().get(0).getEventSourceARN(),
System.lineSeparator());
log.info("ingestionServiceFactory = {}",ingestionServiceFactory);
ingestionServiceFactory.ingest();
return null;
}
}
完整的代码和pom上传到: https://github.com/rjavaria/eventhub-serverless
KinesisEventFunction 应用调用... 还能够从 lambda 读取环境值(source_domain),并接收 Kinesis 事件记录。
但是@Autowired ingestionServiceFactory 为空。我正在注入这个组件bean 来委派业务逻辑。
这里遗漏了什么,所以spring不能注入这个组件bean?
提前致谢!
【问题讨论】:
-
我怀疑
@ComponentScan。不确定它是否包括com.poc.evthub.service。 -
感谢词典。 ComponentScan 不是问题,组件是自动连接的,如果我不将该函数注册为功能 bean 并且不实现 ApplicationContextInitializer。如果它作为 SpringApplication 运行,而不是 FunctionalSpringApplication 并且没有实现 ApplicationContextInitializer,则工作正常。 public static void main(String[] args) throws Exception { SpringApplication.run(EventHubServerlessApplication.class, args); }
标签: spring amazon-web-services aws-lambda amazon-kinesis spring-cloud-function