当前位置: 首页 > 知识库问答 >
问题:

在Amazon AWS lambda中使用Spring boot/cloud不会注入值

方承弼
2023-03-14

我有一个 AWS lambda RequestHandler 类,它由 AWS 直接调用。最终,我需要让它与Spring Boot一起使用,因为我需要它能够从Spring Cloud配置服务器检索数据。

问题是,如果我从自己的开发环境本地运行代码,但在AWS上部署时无法注入配置值,那么代码可以正常工作。

@Configuration
@EnableAutoConfiguration
@ComponentScan("my.package")
public class MyClass implements com.amazonaws.services.lambda.runtime.RequestHandler<I, O> {
   public O handleRequest(I input, Context context) {
        ApplicationContext applicationContext = new SpringApplicationBuilder()
                .main(getClass())
                .showBanner(false)
                .web(false)
                .sources(getClass())
                .addCommandLineProperties(false)
                .build()
                .run();

        log.info(applicationContext.getBean(SomeConfigClass.class).foo);
        // prints cloud-injected value when running from local dev env
        //
        // prints "${path.to.value}" literal when running from AWS 
        //    even though Spring Boot starts successfully without errors
   }
}

@Configuration
public class SomeConfigClass {
   @Value("${path.to.value}")
   public String foo;
}

src/main/resources/bootstrap.yml:
spring:
  application:
    name: my_service
cloud:
  config:
    uri: http://my.server
    failFast: true
    profile: localdev

我尝试了什么:

  • 使用常规的Spring MVC,但这没有与@Value注入/Spring Cloud集成。
  • 使用@PropertySource - 但发现它不支持.yml文件
  • 验证以确保配置服务器正在向任何IP地址提供请求(没有IP地址过滤)
  • 运行卷曲以确保价值被带回来
  • 验证以确保.jar实际上在jar根部包含bootstrap.yml
  • 验证以确保.jar实际包含 Spring Boot 类。FWIW 我正在使用 Maven 阴影插件,它将项目打包成一个包含所有依赖项的胖.jar。

注意:AWS Lambda不支持环境变量,因此我不能设置像spring.application.name这样的东西(既不是环境变量也不是-D参数)。我也不能控制实际启动MyClass的底层类-这对最终用户是完全透明的。我只是打包jar并提供切入点(类名),其余的就交给我了。

有什么我可能错过的吗?我有没有办法调试得更好?

共有1个答案

江迪
2023-03-14

经过一段时间的调试,我发现问题出在使用Maven Shade插件上。Spring Boot在它的自动配置jar中寻找一个META-INF/spring.factories jar。为了正确地打包Spring Boot jar,你需要使用Spring Boot Maven插件,并设置它在Maven重新打包阶段运行。它在您的本地IDE中工作的原因是因为您没有运行Shade打包的jar。他们在插件中使用了一些特殊的魔法来把东西放到正确的位置,而Shade插件并没有意识到这一点。

我能够创建一些示例代码,这些代码最初没有注入值,但现在我使用了正确的插件, 这些代码可以正常工作。请参阅此 GitHub 存储库,了解我所做的工作。

我没有将其与Spring Cloud连接,但现在Spring Boot注入的其余部分正在工作,我认为它应该很简单。

正如我在评论中提到的,您可能只需要考虑一个简单的REST调用来获取云配置并自己注入它,以节省每次请求加载Spring应用程序的开销。

更新:对于Spring Boot 1.4.x,您必须在Spring Boot插件中提供此配置:

            <configuration>
                <layout>MODULE</layout>
            </configuration>

如果没有,那么默认情况下,插件的新行为是将所有jar放在BOOT-INF下,因为目的是让jar可执行并让引导程序加载它。我在为这里遇到的情况添加警告时发现了这一点。请参考https://github.com/spring-projects/spring-boot/issues/5465。

 类似资料:
  • 我正在使用以下依赖项: 创建了新的测试类: 我在Spring Boot中创建了测试用例,但是我得到了这个错误: 这是我的应用程序类: 知道我为什么不能在测试类中注入bean吗? 我按照建议删除了@ContextConfiguration,@ComponentScan,@ConnecationTes现在我看到了不同的异常:

  • 本文向大家介绍在springboot中使用注解将值注入参数的操作,包括了在springboot中使用注解将值注入参数的操作的使用技巧和注意事项,需要的朋友参考一下 后端的许多管理系统需要登陆者的信息,如shiro登陆后,会将登陆者的信息存储在shiro的session,在使用时需要多行代码获取用户信息。可以把获取在shiro中的登陆者信息封装在一个类中,使用时获取。本文主要讲述如何使用注解将值注入

  • 问题内容: 我使用SpringBeanAutowiringSupport在某些对象中进行bean注入。问题是,在jUnit测试中无法注入bean。为了进行测试,使用了SpringJUnit4ClassRunner。 有谁知道,为什么使用注入在jUnit测试中不起作用? 问题答案: 感谢M. Denium的帮助,他的解决方案得以奏效。

  • 我有一个控制器 服务接口 我想在我的控制器中使用@autowired来使用该服务,但当我运行应用程序时,我得到以下错误 org.springframework.beans.factory.beanCreationException:创建名为“demo application”的bean时出错:注入autowired依赖项失败;嵌套异常为org.SpringFramework.Beans.Facto

  • 项目: el-admin 后台 代码如下 deptService 对象没有用过注解, 为什么还能调用 deptService.download ? 有没有大佬知道这个对象是怎么被实例化的? 完整的 DeptController 代码如下

  • 我有这个问题,我不确定这是否是“预期”行为,但我的问题是: 我有一个Http筛选器: UserInfo和ActivationInfo都是@SessionScope,如下所示: 和 当我尝试访问调用过滤器的页面时,我在控制台上看到以下内容: 如果我转到不同的浏览器并输入“坏”校验码,用户信息/激活信息永远不会重新注入。IE,与不同的会话,我没有看到一个新的UserInfo/ActivationInf