Creating an Enterprise OSS Object Storage Spring Boot Starter Based on Amazon S3
This article provides a step‑by‑step guide to building a Spring Boot starter that abstracts OSS object‑storage services via the Amazon S3 protocol, covering project setup, Maven dependencies, configuration properties, template interfaces, implementation, auto‑configuration, packaging, and testing.
Introduction
The article explains how to create an enterprise‑grade OSS (Object Storage Service) Spring Boot starter that works out‑of‑the‑box and can be used with various cloud storage providers such as Alibaba Cloud OSS, Tencent COS, Qiniu OSS, and MinIO by leveraging the Amazon S3 protocol.
What is OSS?
OSS is a service that stores and retrieves objects over HTTP APIs, offering features like file upload/download, preview, versioning, permission control, and lifecycle management.
Why Use Amazon S3 as the Underlying Protocol
Most commercial OSS providers are compatible with the Amazon S3 API, so implementing a starter on top of S3 ensures seamless migration and uniform configuration across different vendors.
Creating the Spring Boot Project
Generate a new Spring Boot project named oss-spring-boot-starter and add the required Maven dependencies.
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3 -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.12.423</version>
</dependency> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" ...>
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- AWS S3 SDK -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>${aws.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>Defining Configuration Properties (OssProperties)
Create a POJO annotated with @ConfigurationProperties(prefix = "oss") and Lombok @Data to bind properties such as endpoint, accessKey, secretKey, region, and connection limits.
oss.endpoint=xxx
oss.accessKey=xxx
oss.secretKey=xxx
/**
* @Author 公众号:架构师指南
* @Description Oss配置类
*/
@Data
@ConfigurationProperties(prefix = "oss")
public class OssProperties {
private String endpoint;
private String region;
private Boolean pathStyleAccess = true;
private String accessKey;
private String secretKey;
private Integer maxConnections = 100;
}Creating the OssTemplate Interface
Define an interface that declares common OSS operations such as bucket management, file upload/download, URL generation, and object listing.
public interface OssTemplate {
void createBucket(String bucketName);
List
getAllBuckets();
void removeBucket(String bucketName);
void putObject(String bucketName, String objectName, InputStream stream, String contentType) throws Exception;
void putObject(String bucketName, String objectName, InputStream stream) throws Exception;
S3Object getObject(String bucketName, String objectName);
String getObjectURL(String bucketName, String objectName, Integer expires);
void removeObject(String bucketName, String objectName) throws Exception;
List
getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive);
}Implementing OssTemplate (OssTemplateImpl)
Provide a concrete class that injects AmazonS3 and implements all methods using the AWS SDK. Lombok annotations @RequiredArgsConstructor and @SneakyThrows simplify boilerplate.
@RequiredArgsConstructor
public class OssTemplateImpl implements OssTemplate {
private final AmazonS3 amazonS3;
@Override
@SneakyThrows
public void createBucket(String bucketName) {
if (!amazonS3.doesBucketExistV2(bucketName)) {
amazonS3.createBucket(bucketName);
}
}
@Override
@SneakyThrows
public List
getAllBuckets() {
return amazonS3.listBuckets();
}
// ... other methods omitted for brevity ...
private PutObjectResult putObject(String bucketName, String objectName, InputStream stream, long size, String contentType) {
byte[] bytes = IOUtils.toByteArray(stream);
ObjectMetadata meta = new ObjectMetadata();
meta.setContentLength(size);
meta.setContentType(contentType);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
return amazonS3.putObject(bucketName, objectName, bais, meta);
}
}Auto‑Configuration (OssAutoConfiguration)
Configure beans for AmazonS3 and OssTemplate using Spring Boot’s conditional annotations.
@Configuration
@RequiredArgsConstructor
@EnableConfigurationProperties(OssProperties.class)
public class OssAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public AmazonS3 ossClient(OssProperties props) {
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setMaxConnections(props.getMaxConnections());
AwsClientBuilder.EndpointConfiguration endpoint = new AwsClientBuilder.EndpointConfiguration(props.getEndpoint(), props.getRegion());
AWSCredentials creds = new BasicAWSCredentials(props.getAccessKey(), props.getSecretKey());
AWSCredentialsProvider provider = new AWSStaticCredentialsProvider(creds);
return AmazonS3Client.builder()
.withEndpointConfiguration(endpoint)
.withClientConfiguration(clientConfig)
.withCredentials(provider)
.disableChunkedEncoding()
.withPathStyleAccessEnabled(props.getPathStyleAccess())
.build();
}
@Bean
@ConditionalOnBean(AmazonS3.class)
public OssTemplate ossTemplate(AmazonS3 amazonS3) {
return new OssTemplateImpl(amazonS3);
}
}spring.factories Registration
Add the auto‑configuration class to META-INF/spring.factories so Spring Boot can discover it automatically.
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.qing.oss.OssAutoConfigurationPackaging and Installation
Run mvn install after removing the Spring Boot Maven plugin from the pom to avoid build errors. Optionally add the Maven source plugin to generate a sources JAR with Javadoc.
<build>
<plugins>
<!-- remove spring-boot-maven-plugin for this starter -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>Testing the Starter
Create a separate Spring Boot application, add the starter as a dependency, configure oss.endpoint , oss.accessKey , and oss.secretKey , then write a simple test that creates a bucket.
@SpringBootTest
class TestOssSpringBootStarterApplicationTests {
@Autowired
private OssTemplate ossTemplate;
@Test
void contextLoads() {
ossTemplate.createBucket("oss02");
}
}After running the test, verify the bucket appears in the chosen OSS provider (e.g., MinIO).
Conclusion
The guide demonstrates how to encapsulate OSS operations into a reusable Spring Boot starter, making object‑storage integration simple, portable, and maintainable across multiple cloud vendors.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.