In the daily development, the existence of such a scenario, the interface framework provides one kind of A default implementation AImpl, along with the demand for change, today AImpl not meet the functional needs, then, how can we do? Of course, is to modify AImpl implementation code, but, if it is dependent on a third party it? Or, we wrote out of a function module, AImpl a default implementation provided us for this module, users can use it, it can also be covered on request (or an extension), how to do?
In this regard, spring offers us @Conditional notes, using it can solve such problems.
Here, for example. There RandomGenerator interface, the interface which has a Generator () method to generate a random string, and there are two implementation classes StringRandomGenerator NumberRandomGenerator, wherein StringRandomGenerator is the default implementation. That is, when we do not configure NumberRandomGenerator, uses StringRandomGenerator generate a random string, when we have configured NumberRandomGenerator, uses NumberRandomGenerator generate a random string.
/ ** * top level interface generates a random string * / 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; } }
/ ** * When the NumberRandomGenerator registered as spring bean, StringRandomGenerator failure * equivalent generator function generator NumberRandomGenerator a method of covering the StringRandomGenerator * / @Component public class NumberRandomGenerator the implements randomGenerator { @Override public Object generator () { String Random = RandomStringUtils.random (. 5, to true , to true ); return "NumberRandomGenerator:" + Random; } }
/ ** * configuration class * / @SpringBootConfiguration public class RandomGeneratorConfig { / ** * @ConditionalOnMissingBean (= RandomGenerator.class value) * the annotation means: if the container is not Ioc RandomGenerator the bean type * will register to StringRandomGenerator Ioc container * / @Bean @ConditionalOnMissingBean (value . randomGenerator = class ) public randomGenerator stringRandomGenerator () { return new new stringRandomGenerator (); } }
Finally, write a test controller
@RestController public class RandomController { @Autowired private RandomGenerator randomGenerator; @GetMapping("/random") public Object random() { return randomGenerator.generator(); } }
In the case where the registered NumberRandomGenerator Ioc container, the test results are as follows:
Next, we will comment on NumberRandomGenerator class @Component kill, then test
perfect!