关于@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自动注入。
这个操作是不会报错的。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
Netty分布式ByteBuf使用SocketChannel读取数据过程剖析
这篇文章主要为大家介绍了Netty源码分析ByteBuf使用SocketChannel读取数据过程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-03-03
最新评论