如何在AWS Lambda中不依赖Spring Boot与Tomcat使用Spring Data REST
在AWS Lambda中使用Spring Data REST(无重型Spring Boot依赖)
这个需求我刚好折腾过,要在Lambda里用Spring Data REST又要轻量化,核心就是砍掉Spring Boot的嵌入式容器和自动配置冗余,只保留最核心的组件。下面一步步来帮你实现:
1. 依赖选型:只挑必要的
绝对不能用spring-boot-starter-web或spring-boot-starter-data-rest(前者带Tomcat,后者依赖前者)。直接引入核心组件,确保依赖极简:
Maven pom.xml示例
<dependencies> <!-- Spring Data REST核心(不带容器) --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-rest-webmvc</artifactId> <version>3.5.12</version> <!-- 注意和Spring版本对齐 --> </dependency> <!-- Spring JPA持久层支持 --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>2.5.12</version> </dependency> <!-- Spring核心上下文 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.27</version> </dependency> <!-- Spring Web核心(提供Servlet API,不带容器) --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.3.27</version> </dependency> <!-- AWS Lambda核心依赖 --> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.21</version> </dependency> <!-- API Gateway事件处理 --> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>3.11.1</version> </dependency> <!-- 简化Lambda与Spring MVC的适配 --> <dependency> <groupId>com.amazonaws.serverless</groupId> <artifactId>aws-serverless-java-container-spring</artifactId> <version>2.0.11</version> </dependency> <!-- 数据库驱动(按需选择,这里用H2做示例) --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.2.224</version> <scope>runtime</scope> </dependency> </dependencies>
注意:所有Spring相关组件版本必须对齐,避免兼容性问题。
2. 手动配置Spring上下文(拒绝自动配置冗余)
不用@SpringBootApplication,而是用纯@Configuration手动组装组件,只加载你需要的功能:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import javax.sql.DataSource; import java.util.Properties; @Configuration @EnableWebMvc // 启用Spring MVC核心(无嵌入式容器) @EnableJpaRepositories(basePackages = "com.yourpackage.repositories") @EnableRestRepositories(basePackages = "com.yourpackage.repositories") public class AppConfig implements RepositoryRestConfigurer { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { // 配置REST基础路径和HATEOAS支持 config.setBasePath("/api"); // 所有REST端点前缀 config.exposeIdsFor(Product.class); // 可选:暴露实体ID在响应中 // 默认已开启HATEOAS,会自动生成HAL格式的链接 } // 手动配置数据源 @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("org.h2.Driver"); dataSource.setUrl("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1"); dataSource.setUsername("sa"); dataSource.setPassword(""); return dataSource; } // 手动配置JPA实体管理器 @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource); em.setPackagesToScan("com.yourpackage.entities"); em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); em.setJpaProperties(hibernateProperties()); return em; } private Properties hibernateProperties() { Properties properties = new Properties(); properties.setProperty("hibernate.hbm2ddl.auto", "create-drop"); properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); return properties; } }
3. Lambda入口:连接API Gateway与Spring MVC
用AWS官方的aws-serverless-java-container-spring库自动处理请求转换,不用自己写Servlet包装类:
import com.amazonaws.serverless.exceptions.ContainerInitializationException; import com.amazonaws.serverless.proxy.spring.SpringLambdaContainerHandler; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class LambdaHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> { // 冷启动时初始化一次Spring上下文 private static final SpringLambdaContainerHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> handler; static { try { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); handler = SpringLambdaContainerHandler.getAwsProxyHandler(context); } catch (ContainerInitializationException e) { e.printStackTrace(); throw new RuntimeException("Spring容器初始化失败", e); } } @Override public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) { // 直接转发请求给Spring MVC处理 return handler.proxy(input, context); } }
4. 实现Entity和Repository
写一个简单的实体和Repository,Spring Data REST会自动生成CRUD端点并支持HATEOAS:
实体类
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Product { @Id @GeneratedValue private Long id; private String name; private Double price; // Getters & Setters }
Repository接口
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.rest.core.annotation.RepositoryRestResource; @RepositoryRestResource(collectionResourceRel = "products", path = "products") public interface ProductRepository extends JpaRepository<Product, Long> { }
现在你已经拥有了完整的CRUD端点,比如:
GET /api/products:获取所有产品(带HATEOAS链接)POST /api/products:创建产品GET /api/products/{id}:获取单个产品PUT /api/products/{id}:更新产品DELETE /api/products/{id}:删除产品
5. 优化启动速度与包大小
- 开启Lambda SnapStart:把冷启动时间压缩到几百毫秒,非常适合Spring应用
- 依赖分层:把Spring相关重型依赖打包到Lambda层,业务代码包只保留自己的代码
- 排除冗余依赖:用
mvn dependency:tree检查依赖树,排除不需要的组件 - 可选:GraalVM原生镜像:追求极致启动速度的话,可以编译成原生镜像(注意Spring Data REST的兼容性)
6. 本地测试
用AWS SAM CLI本地测试:
- 编写
template.yaml定义API Gateway和Lambda - 执行
sam build构建项目 - 执行
sam local start-api启动本地服务,用curl测试端点:curl http://localhost:3000/api/products
内容的提问来源于stack exchange,提问作者Abdeali Chandanwala
相关产品推荐
相关产品推荐

