• @ConditionalOnMissingBean在很多spring框架里都得到很广泛的应用,如spring-boot-starter-security,spring-cloud-starter-oauth2中的应用。
  • 注意@ConditionalOnMissingBean这种注解需要添加在@Bean上面,而不是添加到@Service,@Component等上面。

之前写过关于@ConditionalOnMissingBean注解的用过springboot~@ConditionalOnMissingBean注解的作用​,主要是根本的使用方法,而本篇主要阐述它在​​可扩展性​​上的应用,通过一个例子来说明问题,以讲故事的方式来阐述给大家听:

  • 从前,有一个接口,它提供一个hello方法
public interface MissingBean {
void hello();
}
  • 它有一个默认的实现,当没有其它实现时,就用这个默认的实现
public class DefaultMissingBean implements MissingBean {
@Override
public void hello() {
System.out.println("default MissingBean");
}
}
  • 通过配置类,将MissingBean的默认bean注册到ioc容器中,并声明为​​@ConditionalOnMissingBean​​,缺省的,默认的bean实例。
@Configuration
public class MissingBeanConfig {
@Bean
@ConditionalOnMissingBean(MissingBean.class)
public MissingBean defaultMissingBean() {
return new DefaultMissingBean();
}
}
  • 开发人员在程序中调用了MissingBean,并输出了默认的结果
@RunWith(SpringRunner.class)
@SpringBootTest()
public class ConditionalOnClassTest {

@Autowired
MissingBean missingBean;

/**
* @ConditionalOnMissingBean.
*/
@Test
public void onMissingBean() {
missingBean.hello();
}
}

springboot~@ConditionalOnMissingBean一切为了可扩展性_ide

  • 在具体项目中,开发人员觉得默认的DefaultMissingBean实现不能满足自己的要求,这时,它会进行扩展,添加了第一版实现V1MissingBean
@Component
public class V1MissingBean implements MissingBean {
@Override
public void hello() {
System.out.println("v1 MissingBean");
}
}
  • 这时,程序中的代码引用是不需要修改的,还是上面的代码,我们看一下输出的结果,它将是v1版本的结果
  • springboot~@ConditionalOnMissingBean一切为了可扩展性_ide_02

本人觉得,这才是@ConditionalOnMissingBean等一系列修饰@Bean注解的实际用法,也是spring真正的用义。

作者:仓储大叔,张占岭,
荣誉:微软MVP