關(guān)于@Component和@Bean使用注意
@Component和@Bean使用注意
大家都知道@Component和@Bean是spring生成bean對象的注解,@Component只可以加在類上,如果該類在spring的掃描路徑之下就可以生成bean對象,@Bean一般與@Configuration結(jié)合使用,指定方法名為bean對象的名稱,返回對象為bean對象。
正常情況的使用大家肯定都沒有問題,下面列舉幾種需要注意的情況:
項目結(jié)構(gòu)

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);
}
}結(jié)果如下:
DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean'
Bean{name='A'}
可以看出@Bean會覆蓋@Component結(jié)果。
以springboot方式啟動
結(jié)果如下:
***************************
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
根據(jù)提示可以看出需要在配置文件增加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中已經(jīng)存在一個bean的BeanDefinition了,那么會把之前的這個BeanDefinition的isFactoryMethodUnique修改為false,并且不會生成新的BeanDefinition了。
并且后續(xù)在根據(jù)BeanDefinition創(chuàng)建Bean時,會根據(jù)isFactoryMethodUnique來操作,如果為true,那就表示當(dāng)前BeanDefinition只對應(yīng)了一個方法,那也就是只能用這個方法來創(chuàng)建Bean了,但是如果isFactoryMethodUnique為false,那就表示當(dāng)前BeanDefition對應(yīng)了多個方法,用推斷構(gòu)造方法的邏輯,去選擇用哪個方法來創(chuàng)建Bean。
其屬性會將spring的bean自動注入。
這個操作是不會報錯的。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring @Primary作用和實現(xiàn)原理詳解
今天分享一下Spring中的@Primary注解,Primary的意思是主要的,我們在使用spring的時候,難免會定義多個類型相同的bean,這時候如果不采取一些方法,那么是無法正常使用bean的,所以本就給大家介紹Spring @Primary的作用和實現(xiàn)原理2023-07-07
Java?HttpURLConnection使用方法與實例演示分析
這篇文章主要介紹了Java?HttpURLConnection使用方法與實例演示,HttpURLConnection一個抽象類是標(biāo)準(zhǔn)的JAVA接口,該類位于java.net包中,它提供了基本的URL請求,響應(yīng)等功能,下面我們來深入看看2023-10-10

