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


    需求

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

    准备

    一个接口,有doSomething()方法

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

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

    源代码

    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";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    测试结果

    demoService
    com.example.testtwo.DemoService@75d2647f
    my-own-name-2
    com.example.testtwo.DemoService2@1a5055cf
    demoService3
    com.example.testtwo.DemoService3@fe6916c
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    策略模式实现

    需求

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

    准备

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

    public interface UploadStrategy {
        String uploadFile(MultipartFile file, String path);
        String uploadFile(String fileName, InputStream inputStream, String path);
    }
    
    • 1
    • 2
    • 3
    • 4

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

    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    具体实现

    Oss

    @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());
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    Minio

    @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();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    枚举

    // 把复杂的方法名与实际技术名词对应
    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;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    使用

    @Autowired
    private Map<String, UploadStrategy> uploadStrategyMap; // 自动注入UploadStrategy接口的实现类
    
    uploadStrategyMap.get(getStrategy("oss")).uploadFile(file, path); // 先根据技术名词获得策略具体实现方法名,再从map中拿到对象,调用对象方法
    
    • 1
    • 2
    • 3
    • 4

    参考

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

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

  • 相关阅读:
    基于8086汽车智能小车控制系统
    LeetCode977. 有序数组的平方
    在word、ppt、excel编辑软件标题栏顶部左上角加入自定义功能:另存为、导出PDF
    PHP代码审计10—命令执行漏洞
    .NET性能优化-使用ValueStringBuilder拼接字符串
    写给所有程序员的对象的一封信
    30岁了开始自学编程,家里比较困难还来得及吗?
    writev函数的使用测试
    第二章:线程基础知识复习
    JAVA面试技巧之自我介绍
  • 原文地址:https://blog.csdn.net/qq_43140890/article/details/133420298