目录

1、component-scan扫描路径配置错误

2、@Bean + @Conditional修饰,但不满足Conditional条件

3、beanName相同


1、component-scan扫描路径配置错误

  • 默认情况下,SpringBoot的扫描路径为启动类所在包及其子包。
  • 如果配置了component-scan扫描路径,则SpringBoot启动时会去扫描指定路径下的Bean。
  • 如果@Bean定义不在扫描路径下,则不会将该Bean注册到IOC容器中。

如下所示:

扫描路径配置为com.example.springboot.demo.handler。

则不会扫描ioc包下的@Bean定义。

@SpringBootApplication
@ComponentScan(basePackages = "com.example.springboot.demo.handler")
public class DemoApplication {
    public static void main(String[] args) {
        System.out.println(System.getProperty("user.dir"));
        SpringApplication.run(DemoApplication.class, args);
    }
}

2、@Bean + @Conditional修饰,但不满足Conditional条件

如下所示,条件永远不会满足,所以就不会将MyUser注册到IOC容器。

@Configuration
public class IocRegistry1 {
    @Bean
    // 不存在IocRegistry1的class文件时,才会注册Bean。显然这是个恒为false的条件。
    @ConditionalOnMissingClass("com.example.springboot.demo.ioc.IocRegistry1")
    public MyUser getMyUser1() {
        return new MyUser();
    }
}

3、beanName相同

        如果配置spring.main.allow-bean-definition-overriding=true,并且有多个BeanName相同的Bean定义,这种情况下,其中的某些Bean就会被覆盖。

        @Bean修饰的方法,如果不指定BeanName,默认会以方法名作为BeanName。

        如下图所示,在不同类中有两个方法名相同的Bean定义,虽然返回类型不同,但生成的beanName是相同的,因为配置了spring.main.allow-bean-definition-overriding=true,即允许bean定义覆盖,所以以下两个bean只会有一个Bean被注册。

@Configuration
public class IocRegistry1 {
    @Bean
    // BeanName默认取方法名,为getMyUser。
    public MyUser getMyUser() {
        return new MyUser();
    }
}

@Configuration
public class IocRegistry2 {
    @Bean
    // BeanName默认取方法名,为getMyUser。
    public User getMyUser() {
        return new User();
    }
}

以上内容为个人学习理解,如有问题,欢迎在评论区指出。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐