How to Build a Spring Boot Starter for Multi‑Cloud Object Storage (OSS)
This step‑by‑step guide explains why Amazon S3 is chosen as a universal protocol, walks through creating a Spring Boot project, defining configuration properties, implementing an OSS template, auto‑configuring beans, packaging the starter, and testing it against services like MinIO, Alibaba OSS, and Tencent COS.
Problem and Rationale
Enterprise projects need a unified way to access Object Storage Service (OSS) providers such as Alibaba Cloud OSS, Tencent COS, Qiniu OSS, and MinIO. All major providers implement the Amazon S3 REST API, so a Spring Boot starter that targets the S3 protocol can work with any of them by only changing the endpoint and credentials.
Project Setup
Create a Maven module named oss-spring-boot-starter with Java 1.8 and Lombok. Remove the default application class, test sources, and the spring-boot-maven-plugin from pom.xml to avoid packaging errors.
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.12.423</version>
</dependency>Configuration Properties
Define a POJO that binds oss.* entries from application.yml or .properties:
@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;
}Typical configuration file:
oss.endpoint=https://minio.example.com
oss.region=us-east-1
oss.pathStyleAccess=true
oss.accessKey=YOUR_KEY
oss.secretKey=YOUR_SECRET
oss.maxConnections=100OSS Template Interface
public interface OssTemplate {
void createBucket(String bucketName);
List<Bucket> 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<S3ObjectSummary> getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive);
}Implementation (OssTemplateImpl)
The implementation delegates to the Amazon S3 Java SDK. Example for bucket creation:
@Override
@SneakyThrows
public void createBucket(String bucketName) {
if (!amazonS3.doesBucketExistV2(bucketName)) {
amazonS3.createBucket(bucketName);
}
}Other methods follow the same pattern, using SDK calls such as listBuckets(), deleteBucket(), putObject(), generatePresignedUrl(), and listObjects(). A private helper converts an InputStream to a byte array, sets ObjectMetadata, and uploads the object.
Auto‑Configuration
@Configuration
@EnableConfigurationProperties(OssProperties.class)
@RequiredArgsConstructor
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 credentials = new BasicAWSCredentials(props.getAccessKey(), props.getSecretKey());
AWSCredentialsProvider provider = new AWSStaticCredentialsProvider(credentials);
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);
}
}The spring.factories file registers the configuration:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.qing.oss.OssAutoConfigurationPackaging
Remove the spring-boot-maven-plugin from the build/plugins section of pom.xml. Then run: mvn clean install The resulting JAR is placed in the local Maven repository and can be consumed by other projects.
Testing the Starter
Create a regular Spring Boot application, add the starter as a dependency, and configure the oss.* properties for the target provider (the example uses MinIO). Write a test class:
@SpringBootTest
class TestOssSpringBootStarterApplicationTests {
@Autowired
private OssTemplate ossTemplate;
@Test
void contextLoads() {
ossTemplate.createBucket("oss02");
}
}Running the test creates the bucket in MinIO, confirming that the starter works with any S3‑compatible service.
Conclusion
The guide demonstrates how to wrap the Amazon S3 SDK into a reusable Spring Boot starter that abstracts provider‑specific details, enabling fast integration of Alibaba OSS, Tencent COS, Qiniu OSS, MinIO, and other S3‑compatible services.
Source code: https://github.com/hujiaqing789/test-spring-boot-starter.git
Java Web Project
Focused on Java backend technologies, trending internet tech, and the latest industry developments. The platform serves over 200,000 Java developers, inviting you to learn and exchange ideas together. Check the menu for Java learning resources.
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.
