• Spring框架之接口实现覆盖(接口功能扩展)


      在日常开发中,存在着这种一种场景,框架对接口A提供了一个种默认的实现AImpl,随着需求的变更,现今AImpl不能满足了功能需要,这时,我们该怎么办? 当然是修改AImpl的实现代码了,但是,如果它是第三方依赖呢? 或者说,我们自己写了的某个功能模块,AImpl是我们为此模块提供的一种默认实现,用户可以使用它,也可以按需求进行覆盖(或者说是扩展),该怎么办?

      对此,spring为我们提供了@Conditional注解,使用它可以很好的解决此类问题。

      下面,举个例子。 有个RandomGenerator接口,接口里面有个generator()方法生成随机字符串,有两个实现类StringRandomGenerator和NumberRandomGenerator, 其中StringRandomGenerator是默认实现。也就是说,在我们不配置NumberRandomGenerator时,程序使用StringRandomGenerator生成随机字符串,在我们有配置NumberRandomGenerator时,程序使用NumberRandomGenerator生成随机字符串。

    /**
     * 生成随机字符串的顶层接口
     */
    public interface RandomGenerator {
        Object generator();
    }
    import org.apache.commons.lang.RandomStringUtils;
    
    public class StringRandomGenerator implements RandomGenerator {
        @Override
        public Object generator() {
            char[] chars = {'a','b','c','d','e','f','g'};
            String random = RandomStringUtils.random(5, chars);
            return "StringRandomGenerator:"+random;
        }
    }
    /**
     * 将NumberRandomGenerator 注册成spring bean时,StringRandomGenerator 失效
     * 相当于是NumberRandomGenerator中的generator方法覆盖了 StringRandomGenerator 中的generator方法
     */
    @Component
    public class NumberRandomGenerator implements RandomGenerator {
        @Override
        public Object generator() {
            String random = RandomStringUtils.random(5, true, true);
            return "NumberRandomGenerator:" + random;
        }
    }
    /**
     * 配置类
     */
    @SpringBootConfiguration
    public class RandomGeneratorConfig {
    
        /**
         *  @ConditionalOnMissingBean(value = RandomGenerator.class)
         *  该注解的意思是: 如果Ioc容器中没有 RandomGenerator 类型的 bean时
         *  就将StringRandomGenerator注册到Ioc容器中
         */
        @Bean
        @ConditionalOnMissingBean(value = RandomGenerator.class)
        public RandomGenerator stringRandomGenerator() {
            return new StringRandomGenerator();
        }
    }

    最后写个controller来测试一把

    @RestController
    public class RandomController {
        @Autowired
        private RandomGenerator randomGenerator;
    
        @GetMapping("/random")
        public Object random() {
            return randomGenerator.generator();
        }
    }

    在将NumberRandomGenerator 注册到Ioc容器的情况下,测试结果如下:

    接下来,我们将NumberRandomGenerator类上中@Component注解干掉,再测试

    完美!

  • 相关阅读:
    设计模式——策略模式
    LeetCode
    平凡世界里的万千思绪
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
  • 原文地址:https://www.cnblogs.com/z-qinfeng/p/11785553.html
Copyright © 2020-2023  润新知