多个Bean自动注入成Map @Autowired @Service 策略模式

需求

将多个策略的具体实现自动注入到Map中

准备

一个接口,有doSomething()方法

多个具体实现策略,实现doSomething()方法

一个Controller,用于测试自动注入

源代码

java 复制代码
public interface DemoInterface
{
    void doSomething();
}

@Service
public class DemoService implements DemoInterface
{
    public void doSomething()
    {
        System.out.println("call me");
    }
}

@Service("my-own-name-2")
public class DemoService2 implements DemoInterface
{
    public void doSomething()
    {
        System.out.println("2 call me");
    }
}

@Component
public class DemoService3 implements DemoInterface
{
    public void doSomething()
    {
        System.out.println("3 call me");
    }
}

@RestController
public class DemoController
{
    @Autowired
    private Map<String,DemoInterface> demoServiceMap;
​
    @GetMapping("/test")
    public String test(){
        for(Map.Entry<String, DemoInterface> entry : demoServiceMap.entrySet()){
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        }
        return "succ";
    }
}

测试结果

java 复制代码
demoService
com.example.testtwo.DemoService@75d2647f
my-own-name-2
com.example.testtwo.DemoService2@1a5055cf
demoService3
com.example.testtwo.DemoService3@fe6916c

策略模式实现

需求

文件上传功能,可以使用oss和minio两种方式

准备

策略接口,包含uploadFile()方法

java 复制代码
public interface UploadStrategy {
    String uploadFile(MultipartFile file, String path);
    String uploadFile(String fileName, InputStream inputStream, String path);
}

抽象实现,抽象出一些公共逻辑,留出不同策略区别的方法进一步具体实现(非必要)

java 复制代码
public abstract class AbstractUploadStrategyImpl implements UploadStrategy{
    @Override
    public String uploadFile(MultipartFile file, String path) {
        try {
            String md5 = FileUtil.getMd5(file.getInputStream());
            String extName = FileUtil.getExtName(file.getOriginalFilename());
            String fileName = md5 + extName;
            if (!exists(path + fileName)) {
                upload(path, fileName, file.getInputStream());
            }
            return getFileAccessUrl(path + fileName);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException("文件上传失败");
        }
    }
    @Override
    public String uploadFile(String fileName, InputStream inputStream, String path) {
        try {
            upload(path, fileName, inputStream); // 具体上传策略
            return getFileAccessUrl(path + fileName); // 具体文件路径
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException("文件上传失败");
        }
    }
    public abstract Boolean exists(String filePath);
​
    public abstract void upload(String path, String fileName, InputStream inputStream) throws IOException;
​
    public abstract String getFileAccessUrl(String filePath);
}

具体实现

Oss

java 复制代码
@Service("ossUploadStrategyImpl")
public class OssUploadStrategyImpl extends AbstractUploadStrategyImpl {

    @Autowired
    private OssConfigProperties ossConfigProperties;

    @Override
    public Boolean exists(String filePath) {
        return getOssClient().doesObjectExist(ossConfigProperties.getBucketName(), filePath);
    }

    @Override
    public void upload(String path, String fileName, InputStream inputStream) {
        getOssClient().putObject(ossConfigProperties.getBucketName(), path + fileName, inputStream);
    }

    @Override
    public String getFileAccessUrl(String filePath) {
        return ossConfigProperties.getUrl() + filePath;
    }

    private OSS getOssClient() {
        return new OSSClientBuilder().build(ossConfigProperties.getEndpoint(), ossConfigProperties.getAccessKeyId(), ossConfigProperties.getAccessKeySecret());
    }

}

Minio

java 复制代码
@Service("minioUploadStrategyImpl")
public class MinioUploadStrategyImpl extends AbstractUploadStrategyImpl {

    @Autowired
    private MinioProperties minioProperties;

    @Override
    public Boolean exists(String filePath) {
        boolean exist = true;
        try {
            getMinioClient()
                    .statObject(StatObjectArgs.builder().bucket(minioProperties.getBucketName()).object(filePath).build());
        } catch (Exception e) {
            exist = false;
        }
        return exist;
    }

    @SneakyThrows
    @Override
    public void upload(String path, String fileName, InputStream inputStream) {
        getMinioClient().putObject(
                PutObjectArgs.builder().bucket(minioProperties.getBucketName()).object(path + fileName).stream(
                                inputStream, inputStream.available(), -1)
                        .build());
    }

    @Override
    public String getFileAccessUrl(String filePath) {
        return minioProperties.getUrl() + filePath;
    }

    private MinioClient getMinioClient() {
        return MinioClient.builder()
                .endpoint(minioProperties.getEndpoint())
                .credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey())
                .build();
    }

}

枚举

java 复制代码
// 把复杂的方法名与实际技术名词对应
public enum UploadModeEnum {

    OSS("oss", "ossUploadStrategyImpl"),

    MINIO("minio", "minioUploadStrategyImpl");

    private final String mode;

    private final String strategy;

    public static String getStrategy(String mode) {
        for (UploadModeEnum value : UploadModeEnum.values()) {
            if (value.getMode().equals(mode)) {
                return value.getStrategy();
            }
        }
        return null;
    }

}

使用

java 复制代码
@Autowired
private Map<String, UploadStrategy> uploadStrategyMap; // 自动注入UploadStrategy接口的实现类

uploadStrategyMap.get(getStrategy("oss")).uploadFile(file, path); // 先根据技术名词获得策略具体实现方法名,再从map中拿到对象,调用对象方法

参考

源码:https://github.com/linhaojun857/aurora

原理:https://www.cnblogs.com/lifullmoon/p/14453011.html

相关推荐
tiger从容淡定是人生2 天前
可审计性:AI时代自动化测试的核心指标
人工智能·自动化·项目管理·策略模式·可用性测试·coo
都说名字长不会被发现3 天前
模版方法 + 策略模式在库存增加/扣减场景下的应用
策略模式·模板方法模式·宏命令·策略聚合·库存设计
默|笙3 天前
【Linux】进程概念与控制(2)_进程控制
java·linux·策略模式
枫叶林FYL4 天前
Agent/Teakenote 系统(Swarm 架构)深度技术报告
架构·策略模式
苏渡苇5 天前
枚举的高级用法——用枚举实现策略模式和状态机
java·单例模式·策略模式·枚举·状态机·enum
harder3217 天前
Swift 面向协议编程的 RMP 模式
开发语言·ios·mvc·swift·策略模式
skywalk81638 天前
esxi8 虚拟机中怎么安装mac os(纯AI回答,未实践)
策略模式·esxi
廖圣平8 天前
从零开始,福袋直播间脚本研究【八】《策略模式》
开发语言·python·bash·策略模式
爱学习 爱分享12 天前
简单工厂模式和策略模式的区别
简单工厂模式·策略模式
xcntime15 天前
Python中print函数如何实现不换行输出?
策略模式