傻傻的不知道怎么起文章标题
以前使用的方式
public Class A{
public static Map <String,FatherClass> map = new HashMap<>(16);
static{
map.put(son1Name,son1Class);
map.put(son2Name,son2Class);
}
}
现在使用的方式
自定义注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface FileStoreWay {
String value() default "common";
}
子类(添加自定义注解@FileStoreWay)
package com.hito.base;
import com.amazonaws.AmazonClientException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.transfer.Download;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.Upload;
import com.hito.annotate.FileStoreWay;
import com.hito.entity.FileInfo;
import com.hito.enums.BucketEnum;
import com.hito.enums.FileTypeEnum;
import com.hito.mapper.FileInfoMapper;
import com.hito.util.CephConnectionFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
/**
* @author fuchanghai
*/
@FileStoreWay(value = "ceph")
@Slf4j
public class CephFileOperate extends FileOperate {
@Value("${fileRootPath}")
private String fileRootPath;
@Value("${downloadRootPath}")
private String downloadRootPath;
@Autowired
FileInfoMapper fileInfoMapper;
@Autowired
CephConnectionFactory cephConnectionFactory;
@Override
public void uploadFile(HttpServletRequest request, MultipartFile file) throws IOException {
uploadFile(request, file, BucketEnum.DEFAULT.name());
}
public void uploadFile(HttpServletRequest request, MultipartFile file, String bucketName) throws IOException {
File dest = new File(fileRootPath + file.getOriginalFilename());
file.transferTo(dest);
fragmentUpload(request.getRemoteHost(), dest, bucketName);
}
@Override
public void fragmentUpload(String ip, File dest) {
fragmentUpload(ip, dest, BucketEnum.DEFAULT.name());
}
@Override
public File download(FileInfo fileInfo) {
File file = new File(downloadRootPath + fileInfo.getName());
AmazonS3 connection = cephConnectionFactory.getConnection();
TransferManager transferManager = new TransferManager(connection);
Download download = transferManager.download(fileInfo.getBucketName(), fileInfo.getName(), file);
try {
download.waitForCompletion();
} catch (InterruptedException e) {
e.printStackTrace();
}
return file;
}
public void fragmentUpload(String ip, File dest, String bucketName) {
AmazonS3 connection = cephConnectionFactory.getConnection();
Bucket newBucket = connection.createBucket(bucketName);
TransferManager transferManager = new TransferManager(connection);
Upload upload = transferManager.upload(bucketName, dest.getName(), dest);
try {
upload.waitForCompletion();
log.info("Upload complete.");
} catch (AmazonClientException amazonClientException) {
log.info("Unable to upload file, upload was aborted.");
amazonClientException.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
insertFileInfo(ip, dest, bucketName, FileTypeEnum.CEPH.code(), fileInfoMapper);
}
@Override
public void say() {
System.out.println("ceph 类");
}
}
@Configuration
public class AllFileOperate implements ApplicationContextAware {
public static HashMap<String, FileOperate> fileOperates = new HashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//获取所有加了此注解的类
String[] beanNames = applicationContext.getBeanNamesForAnnotation(FileStoreWay.class);
for (String beanName : beanNames
) {
FileOperate bean = applicationContext.getBean(beanName, FileOperate.class);
fileOperates.put(beanName, bean);
}
}
}
controller 调用
@PostMapping("/upload")
public ApiResponse upload(HttpServletRequest request, @RequestParam("file") MultipartFile file,
@RequestParam(name = "way", defaultValue = "common") String way) throws IOException {
//way 填的是注解 FileStoreWay 里面的value 值
FileOperate fileOperate = AllFileOperate.fileOperates.get(way);
fileOperate.uploadFile(request, file);
return ApiResponse.responseSuccess();
}
为什么要绕这么一大圈
笔者上面做的是 上传下载文件接口,有普通上传下载,有上传到ceph 上 也有上传到fastdfs 上,全都继承了FileOperate 抽象类,如果现在进来一个新需求上传到新的存储介质上,只需要继承fileOperate 并在子类上加上注解@FileStoreWay即可。不需要其他操作,可扩展性比上面强