gpt4 book ai didi

spring - 使用 Spring Cloud 函数 AWS Adapter 运行 AWS lambda 函数时,组件 bean 不会被 spring 注入(inject)( Autowiring )

转载 作者:行者123 更新时间:2023-12-05 07:20:05 24 4
gpt4 key购买 nike

我正在使用 Spring Cloud 函数 AWS Adapter SpringBootRequestHandler 实现 AWS lambda 函数创建处理程序。在 GenericApplicationContext 中注册的功能 bean 被调用,但组件类的 Autowiring 给出 NullPointer 异常。

我已经在 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> {

}

功能性 Bean:

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 是空的。我正在注入(inject)这个组件 bean 来委托(delegate)业务逻辑。

这里遗漏了什么,所以spring不能注入(inject)这个组件bean?

提前致谢!

最佳答案

您可以尝试手动注入(inject)您的 IngestionServiceFactory bean 通过构造函数或 setter 注入(inject)到您的函数类中。

在你的函数类中,添加一个构造函数并删除 @Autowired来自你的 IngestionServiceFactory字段,例如:

...
public class KinesisEventFunction implements Function<KinesisEvent, ApiResponse> {

...
// No @Autowired here...
private final IngestionServiceFactory ingestionServiceFactory;
...
// The new constructor here...
public KinesisEventFunction(final IngestionServiceFactory pIngestionServiceFactory) {
this.ingestionServiceFactory = pIngestionServiceFactory;
}
...

}

然后在您的主类(实现 ApplicationContextInitializer<GenericApplicationContext> 的那个)中,在注册功能 bean 时将引用传递给工厂,例如:

...
public class EventHubServerlessApplication implements ApplicationContextInitializer<GenericApplicationContext> {

...
@Autowired
private IngestionServiceFactory ingestionServiceFactory;
...
@Bean
public KinesisEventFunction ingestEvents() {
return new KinesisEventFunction(this.ingestionServiceFactory);
}

@Override
public void initialize(GenericApplicationContext context) {

log.debug("======== initialize ========");

context.registerBean("ingestEvents", FunctionRegistration.class,
() -> new FunctionRegistration<>(ingestEvents())
.type(FunctionType.from(KinesisEvent.class).to(ApiResponse.class).getType()));
}
}

或者,因为您已经使用 context.registerBean() 手动注册了功能 bean , 你可以:

...
public class EventHubServerlessApplication implements ApplicationContextInitializer<GenericApplicationContext> {

...
@Autowired
private IngestionServiceFactory ingestionServiceFactory;
...
@Override
public void initialize(GenericApplicationContext context) {

log.debug("======== initialize ========");

context.registerBean("ingestEvents", FunctionRegistration.class,
() -> new FunctionRegistration<>(new KinesisEventFunction(this.ingestionServiceFactory))
.type(FunctionType.from(KinesisEvent.class).to(ApiResponse.class).getType()));
}
}

请告诉我它是否有效!

关于spring - 使用 Spring Cloud 函数 AWS Adapter 运行 AWS lambda 函数时,组件 bean 不会被 spring 注入(inject)( Autowiring ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57627545/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com