关于@Component和@Bean使用注意

 更新时间:2023年06月20日 10:04:03   作者:mengyuanye  
这篇文章主要介绍了关于@Component和@Bean使用注意,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

@Component和@Bean使用注意

大家都知道@Component和@Bean是spring生成bean对象的注解,@Component只可以加在类上,如果该类在spring的扫描路径之下就可以生成bean对象,@Bean一般与@Configuration结合使用,指定方法名为bean对象的名称,返回对象为bean对象。

正常情况的使用大家肯定都没有问题,下面列举几种需要注意的情况:

项目结构

1、两个相同名称的类在不同包下加@Component

@Component
public class Bean {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Bean{" +
                "name='" + name + '\'' +
                '}';
    }
}

两个Bean类代码如上,启动项目会报错

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.example.demo.DemoApplication]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'bean' for bean class [com.example.demo.b.Bean] conflicts with existing, non-compatible bean definition of same name and class [com.example.demo.a.Bean]

解决方式:

修改其中一个类的名称,或者在@Component中指定不一样的bean的名称。

2、存在同名的@Bean方法名和@Component类

@Configuration
@ComponentScan("com.example.demo")
public class BeanConfig {
    @Bean
    com.example.demo.a.Bean bean(){
        com.example.demo.a.Bean bean = new com.example.demo.a.Bean();
        bean.setName("A");
        return bean;
    }
}

以spring的方式启动

//@SpringBootApplication
public class DemoApplication {
    @Autowired
    ApplicationContext ioc;
    public static void main(String[] args) {
//        SpringApplication.run(DemoApplication.class, args);
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
        Object bean = applicationContext.getBean("bean");
        System.out.println(bean);
    }
}

结果如下:

 DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean'
Bean{name='A'}

可以看出@Bean会覆盖@Component结果。

以springboot方式启动

结果如下:

***************************
APPLICATION FAILED TO START
***************************

Description:

The bean 'bean', defined in class path resource [com/example/demo/config/BeanConfig.class], could not be registered. A bean with that name has already been defined in file [D:\learn-master\demo\target\classes\com\example\demo\b\Bean.class] and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

根据提示可以看出需要在配置文件增加spring.main.allow-bean-definition-overriding=true

3、如果存在多个@Bean方法名相同重载

@Configuration
@ComponentScan("com.example.demo")
public class BeanConfig {
    @Bean
    com.example.demo.a.Bean bean(){
        com.example.demo.a.Bean bean = new com.example.demo.a.Bean();
        bean.setName("A");
        return bean;
    }
    @Bean
    com.example.demo.a.Bean bean(com.example.demo.a.Bean bean1, com.example.demo.a.Bean bean2){
        com.example.demo.a.Bean bean = new com.example.demo.a.Bean();
        bean.setName("B");
        return bean;
    }
    @Bean
    com.example.demo.a.Bean bean(com.example.demo.a.Bean bean1){
        com.example.demo.a.Bean bean = new com.example.demo.a.Bean();
        bean.setName("C");
        return bean;
    }
}

虽然有三个个@Bean,但是肯定只会生成一个bean的Bean,那么Spring在处理@Bean时,也只会生成一个bean的BeanDefinition,比如Spring先解析到第一个@Bean,会生成一个BeanDefinition,此时isFactoryMethodUnique为true,但是解析到第二个@Bean时,会判断出来beanDefinitionMap中已经存在一个bean的BeanDefinition了,那么会把之前的这个BeanDefinition的isFactoryMethodUnique修改为false,并且不会生成新的BeanDefinition了。  

并且后续在根据BeanDefinition创建Bean时,会根据isFactoryMethodUnique来操作,如果为true,那就表示当前BeanDefinition只对应了一个方法,那也就是只能用这个方法来创建Bean了,但是如果isFactoryMethodUnique为false,那就表示当前BeanDefition对应了多个方法,用推断构造方法的逻辑,去选择用哪个方法来创建Bean。  

其属性会将spring的bean自动注入。  

这个操作是不会报错的。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java zookeeper服务的使用详解

    Java zookeeper服务的使用详解

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等
    2022-08-08
  • Java中四种线程池的使用示例详解

    Java中四种线程池的使用示例详解

    这篇文章主要给大家介绍了关于Java中四种线程池的使用方法,四种线程池分别包括FixedThreadPool、CachedThreadPool、ScheduledThreadPool以及SingleThreadExecutor,文中给出了详细的示例代码供大家参考,需要的朋友们下面来一起看看吧。
    2017-08-08
  • SpringBoot事务注解超详细讲解

    SpringBoot事务注解超详细讲解

    这篇文章主要给大家介绍了关于SpringBoot事务注解的相关资料,在Spring Boot中,事务管理是一个非常重要的概念,我们可以使用事务注解来控制事务的行为,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • Netty分布式ByteBuf使用SocketChannel读取数据过程剖析

    Netty分布式ByteBuf使用SocketChannel读取数据过程剖析

    这篇文章主要为大家介绍了Netty源码分析ByteBuf使用SocketChannel读取数据过程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03
  • Java设计模式之桥接模式的示例详解

    Java设计模式之桥接模式的示例详解

    桥梁模式是对象的结构模式。又称为柄体(Handle and Body)模式或接口(Interface)模式。本文将通过示例来详细讲解一下这个模式,感兴趣的可以学习一下
    2022-02-02
  • java正则表达式提取数字的方法实例

    java正则表达式提取数字的方法实例

    这篇文章主要介绍了java正则表达式提取数字的方法,还有去除字符串数字的方法,大家参考使用吧
    2013-12-12
  • SpringBoot集成MyBatis的多种方式

    SpringBoot集成MyBatis的多种方式

    本文深入解析了Spring Boot集成MyBatis的多种方式,包括XML配置、注解配置以及MyBatis的动态SQL等,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • Spring Data默认值的错误解决

    Spring Data默认值的错误解决

    本文主要介绍了Spring Data默认值的错误解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • java教程之java注解annotation使用方法

    java教程之java注解annotation使用方法

    这篇文章主要介绍了java注解annotation使用方法,注解可以定义到方法上,类上,一个注解相当与一个类,就相当于实例了一个对象,加上了注解,就相当于加了一个标志
    2014-01-01
  • 关于ThreadLocal的用法和说明及注意事项

    关于ThreadLocal的用法和说明及注意事项

    这篇文章主要介绍了关于ThreadLocal的用法和说明及注意事项,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05

最新评论