最近使用七牛云的时候突然想自己制作一个springboot-starter版本,毕竟可以把ak,sk等等直接写在application.yml里实在是很好用啊。于是自己制作了qiniu-spring-boot-starter 0.1 RELEASE版(目前版本有简单上传、覆盖上传和删除文件等)( ̄▽ ̄)~*已经上传到maven中央仓库和mvnrepository了,地址戳->http://mvnrepository.com/artifact/cn.yunlingfly/qiniu-spring-boot-starter,代码放在了github上戳->https://github.com/Yunlingfly/qiniu-starter
使用方法戳->https://github.com/Yunlingfly/qiniu-starter#qiniu-spring-boot-starter
第一次制作,有什么问题可以直接提哈(~ ̄▽ ̄)~
首先给出项目结构:
新建springboot项目,更新pom.xml(这个pom文件有点长,主要是配置了上传到中央仓库必须的属性,详解戳我的另一篇博文->SpringBoot项目发布到Maven中央仓库):
4.0.0
cn.yunlingfly
qiniu-spring-boot-starter
0.1-RELEASE
jar
qiniu-spring-boot-starter
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
2.0.4.RELEASE
oss
https://oss.sonatype.org/content/repositories/snapshots
oss
https://oss.sonatype.org/service/local/staging/deploy/maven2/
release
org.apache.maven.plugins
maven-source-plugin
2.2.1
attach-sources
jar-no-fork
org.apache.maven.plugins
maven-javadoc-plugin
2.9.1
attach-javadocs
jar
org.apache.maven.plugins
maven-gpg-plugin
1.5
sign-artifacts
verify
sign
The Apache Software License, Version 2.0
http://www.apache.org/licenses/LICENSE-2.0.txt
https://github.com/Yunlingfly/qiniu-starter
https://github.com/Yunlingfly/qiniu-starter.git
https://github.com/Yunlingfly
yunlingfly
[email protected]
https://github.com/Yunlingfly
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-configuration-processor
true
org.springframework.boot
spring-boot-autoconfigure
com.alibaba
fastjson
1.2.10
org.springframework.boot
spring-boot-starter
com.qiniu
qiniu-java-sdk
7.1.0
org.springframework.boot
spring-boot-starter-test
test
org.apache.maven.plugins
maven-compiler-plugin
1.8
org.sonatype.plugins
nexus-staging-maven-plugin
1.6.7
true
oss
https://oss.sonatype.org/
true
1 首先编写读取yaml配置的QiNiuProperties:
package cn.yunlingfly.qiniuspringbootstarter.infra.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* 七牛云属性配置
*
* @author yunlingfly@csdn
*/
@Component
@ConfigurationProperties(prefix = "qiniu")
public class QiNiuProperties {
/**
* 七牛云的密钥
*/
private String accessKey = "access-key";
private String secretKey = "secret-key";
/**
* 存储空间名字
*/
private String bucketName = "bucket-name";
/**
* 一般设置为cdn
*/
private String cdnPrefix = "cdn";
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getBucketName() {
return bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
public String getCdnPrefix() {
return cdnPrefix;
}
public void setCdnPrefix(String cdnPrefix) {
this.cdnPrefix = cdnPrefix;
}
}
2 编写校验程序QiNiuCondition:
package cn.yunlingfly.qiniuspringbootstarter.infra.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.StringUtils;
/**
* 校验类
*
* @author yunlingfly@csdn
*/
public class QiNiuCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String ak = context.getEnvironment().getProperty("qiniu.access-key");
String sk = context.getEnvironment().getProperty("qiniu.secret-key");
String bucketName = context.getEnvironment().getProperty("qiniu.bucket-name");
if (StringUtils.isEmpty(ak)) {
throw new RuntimeException("Lack of qiniuyun configuration:access-key");
} else if (StringUtils.isEmpty(sk)) {
throw new RuntimeException("Lack of qiniuyun configuration:qiniu.secret-key");
} else if (StringUtils.isEmpty(bucketName)) {
throw new RuntimeException("Lack of qiniuyun configuration:qiniu.bucket-name");
} else {
return true;
}
}
}
3 编写供调用的接口IQiniuService :
package cn.yunlingfly.qiniuspringbootstarter.api.service;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import java.io.File;
/**
* IQiniuService接口
*/
public interface IQiniuService {
/**
* 上传文件
* 文件上传
*
* @param file 填写上传文件File类型
* @param key 添加上传的key值
* @param existed 是否已经存在
* @return 返回com.qiniu.http.Response
* @throws QiniuException 抛出QiniuException异常
*/
Response uploadFile(File file, String key, boolean existed) throws QiniuException;
/**
* 上传文件
* 文件路径上传
*
* @param filePath 填写上传文件的位置
* @param key 添加上传的key值
* @param existed 是否已经存在
* @return 返回com.qiniu.http.Response
* @throws QiniuException 抛出QiniuException异常
*/
Response uploadFile(String filePath, String key, boolean existed) throws QiniuException;
/**
* 删除
*
* @param key 添加上传的key值
* @throws QiniuException 抛出QiniuException异常
*/
void deleteFile(String key) throws QiniuException;
}
4 接口实现类QiniuServiceImpl :
package cn.yunlingfly.qiniuspringbootstarter.api.service.impl;
import cn.yunlingfly.qiniuspringbootstarter.api.service.IQiniuService;
import cn.yunlingfly.qiniuspringbootstarter.infra.config.QiNiuProperties;
import com.alibaba.fastjson.JSON;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.File;
/**
* service实现类
*
* @author yunlingfly@csdn
*/
@Service
public class QiniuServiceImpl implements IQiniuService {
private static final Logger logger = LoggerFactory.getLogger(QiniuServiceImpl.class);
@Autowired
private UploadManager uploadManager;
@Autowired
private BucketManager bucketManager;
@Autowired
private Auth auth;
@Autowired
private QiNiuProperties qiNiuProperties;
@Override
public Response uploadFile(File file, String key, boolean existed) throws QiniuException {
Response response;
// 覆盖上传
if (existed) {
response = this.uploadManager.put(file, key, getUploadToken(key));
} else {
System.out.println("使用文件上传");
response = this.uploadManager.put(file, key, getUploadToken());
int retry = 0;
while (response.needRetry() && retry < 3) {
response = this.uploadManager.put(file, key, getUploadToken());
retry++;
}
}
return response;
}
@Override
public Response uploadFile(String filePath, String key, boolean existed) throws QiniuException {
Response response;
// 覆盖上传
if (existed) {
response = this.uploadManager.put(filePath, key, getUploadToken(key));
} else {
response = this.uploadManager.put(filePath, key, getUploadToken());
int retry = 0;
while (response.needRetry() && retry < 3) {
response = this.uploadManager.put(filePath, key, getUploadToken());
retry++;
}
}
return response;
}
@Override
public void deleteFile(String key) throws QiniuException {
bucketManager.delete(qiNiuProperties.getBucketName(), key);
}
/**
* 获取上传凭证,覆盖上传
*/
private String getUploadToken(String fileName) {
return this.auth.uploadToken(qiNiuProperties.getBucketName(), fileName);
}
/**
* 获取上传凭证,普通上传
*/
private String getUploadToken() {
return this.auth.uploadToken(qiNiuProperties.getBucketName());
}
/**
* 这个注解在这里没实际用处,就是为了方便在该类构造完成后打印日志,看看配置信息是否加载到配置类中了
*/
@PostConstruct
public void init() {
logger.info("qiNiuProperties: {}", JSON.toJSONString(qiNiuProperties));
}
}
5 自动装配QiNiuYunServiceAutoConfiguration :
package cn.yunlingfly.qiniuspringbootstarter;
import cn.yunlingfly.qiniuspringbootstarter.api.service.IQiniuService;
import cn.yunlingfly.qiniuspringbootstarter.api.service.impl.QiniuServiceImpl;
import cn.yunlingfly.qiniuspringbootstarter.infra.condition.QiNiuCondition;
import cn.yunlingfly.qiniuspringbootstarter.infra.config.QiNiuProperties;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
/**
* 七牛云属性配置
*
* @author yunlingfly@csdn
*/
// 装配配置属性
@Configuration
// 自动装配这个properties类,读取yaml自定义内容
@EnableConfigurationProperties(QiNiuProperties.class)
// service类,@ConditionalOnClass某个 Class 位于类路径上,才会实例化一个Bean。也就是说,当classpath下发现该类的情况下进行实例化。
@ConditionalOnClass(IQiniuService.class)
// 校验类
@Conditional(QiNiuCondition.class)
// 当配置文件中 qiniu 的值为 true 时,实例化此类。可以不填
@ConditionalOnProperty(prefix = "qiniu", value = "true", matchIfMissing = true)
public class QiNiuYunServiceAutoConfiguration {
@Autowired
private QiNiuProperties qiNiuYunProperties;
/// 指定实例化接口的类
@Bean
@ConditionalOnMissingBean(QiniuServiceImpl.class)
public IQiniuService qiNiuYunService() {
return new QiniuServiceImpl();
}
// 构建一个七牛上传工具实例
@Bean
public UploadManager uploadManager() {
return new UploadManager();
}
// 认证信息实例
@Bean
public Auth auth() {
return Auth.create(qiNiuYunProperties.getAccessKey(), qiNiuYunProperties.getSecretKey());
}
// 构建七牛空间管理实例
@Bean
public BucketManager bucketManager() {
return new BucketManager(auth());
}
}
6 让springboot加载我们的装配类,在resource目录下新建METE-INF/spring.factories(文件名不能打错了)内容如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.yunlingfly.qiniuspringbootstarter.QiNiuYunServiceAutoConfiguration
7 写完后就可以发布到maven中央仓库了(如果只是本地用的话直接install就可以在本地m2仓库找到并引用了):
mvn clean deploy -P release
1 新建一个springboot项目,引入我们制作的依赖:
cn.yunlingfly
qiniu-spring-boot-starter
0.1-RELEASE
2 修改application.yml(这里写配置的时候IDEA会有代码提示的哦):
server:
port: 8081
qiniu:
secret-key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
access-key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
bucket-name: xxxxx
3 编写测试Controller类:
package cn.yunlingfly.qiniustarterdemo.controller;
import cn.yunlingfly.qiniuspringbootstarter.api.service.IQiniuService;
import com.qiniu.common.QiniuException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Autowired
IQiniuService qiniuService;
@RequestMapping(value = "qiniu",method = RequestMethod.GET)
public String hello(){
try {
// 参数分别是:上传文件位置、上传key值、是否是覆盖上传
qiniuService.uploadFile("images/1.png","1.png",true);
}catch (QiniuException e){
e.printStackTrace();
return "failed";
}
return "success";
}
}
ps:如果自动注入的时候出现下面的情况是没有问题的,这是spring检查机制的结果,程序是能运行的,如果想改的话可以设置在intellij idea file-settings-editor-Inspections-spring 把右边的Mixed 改为warning
4 运行测试
控制台会打出我定制的信息
发送一个请求: