2

我尝试使用https://spring.io/blog/2018/10/22/functional-bean-registrations-in-spring-cloud-function中提到的功能 bean 注册并将其部署到 AWS Lambda。传统方式工作得很好,请参阅https://github.com/mydeveloperplanet/MySpringCloudFunctionPlanet/tree/feature/aws-funtion-bean-definition中的代码

但是,当我将应用程序转换为函数 bean 样式时,会出现以下错误:

2020-10-24 11:11:42.910  INFO 8 --- [           main] lambdainternal.AWSLambda                 : Starting AWSLambda on 169.254.55.181 with PID 8 (/var/runtime/lib/aws-lambda-java-runtime-0.2.0.jar started by sbx_user1051 in /var/task)
2020-10-24 11:11:42.932  INFO 8 --- [           main] lambdainternal.AWSLambda                 : No active profile set, falling back to default profiles: default
2020-10-24 11:11:44.813  INFO 8 --- [           main] lambdainternal.AWSLambda                 : Started AWSLambda in 4.559 seconds (JVM running for 6.581)
No qualifying bean of type 'org.springframework.cloud.function.context.FunctionCatalog' available: org.springframework.beans.factory.NoSuchBeanDefinitionException
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.function.context.FunctionCatalog' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1127)
    at org.springframework.cloud.function.adapter.aws.FunctionInvoker.start(FunctionInvoker.java:124)
    at org.springframework.cloud.function.adapter.aws.FunctionInvoker.<init>(FunctionInvoker.java:77)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)

END RequestId: 1e5c5105-1be5-4388-81f7-f60c77377036
REPORT RequestId: 1e5c5105-1be5-4388-81f7-f60c77377036  Duration: 6842.67 ms    Billed Duration: 6900 ms    Memory Size: 512 MB Max Memory Used: 47 MB  
Unknown application error occurred
org.springframework.beans.factory.NoSuchBeanDefinitionException

代码如下(可在 GitHub https://github.com/mydeveloperplanet/MySpringCloudFunctionPlanet/tree/master获得):

@SpringBootConfiguration
public class MySpringCloudFunctionPlanetApplication implements ApplicationContextInitializer<GenericApplicationContext> {

    public static void main(String[] args) {
        FunctionalSpringApplication.run(MySpringCloudFunctionPlanetApplication.class, args);
    }

    public Function<String, Boolean> containsCloud() {
        return value -> value.contains("cloud");
    }

    @Override
    public void initialize(GenericApplicationContext context) {
        context.registerBean("containsCloud", FunctionRegistration.class,
                () -> new FunctionRegistration<>(containsCloud())
                        .type(FunctionType.from(String.class).to(Boolean.class)));
    }

}

我在这里想念什么?

4

1 回答 1

2

好吧,在经历了这个兔子洞之后,我终于明白,对我来说,这是因为 Spring 没有找到像 ContextFunctionCatalogAutoConfiguration 这样的 bean。就我而言,原因是我没有从 spring-boot-starter-parent POM 继承,并且那里有关键配置,Maven Shade 插件才能工作。需要将 Shade 插件配置为合并 spring.handlers 和 spring.schemas 文件,以便 Spring 可以发现这些自动注册 FunctionCatalog、Jackson ObjectMapper 等的 bean。

因此,要修复,您可以使用如下配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.4</version>
    <configuration>
        <createDependencyReducedPom>false</createDependencyReducedPom>
        <shadedArtifactAttached>true</shadedArtifactAttached>
        <shadedClassifierName>aws</shadedClassifierName>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.4.1</version>
        </dependency>
    </dependencies>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>

            <configuration>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.handlers</resource>
                    </transformer>
                    <transformer implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer">
                        <resource>META-INF/spring.factories</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.schemas</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>${start-class}</mainClass>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>
于 2020-12-22T17:17:26.033 回答