關于@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了。
并且后續(xù)在根據BeanDefinition創(chuàng)建Bean時,會根據isFactoryMethodUnique來操作,如果為true,那就表示當前BeanDefinition只對應了一個方法,那也就是只能用這個方法來創(chuàng)建Bean了,但是如果isFactoryMethodUnique為false,那就表示當前BeanDefition對應了多個方法,用推斷構造方法的邏輯,去選擇用哪個方法來創(chuàng)建Bean。
其屬性會將spring的bean自動注入。
這個操作是不會報錯的。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Java?HttpURLConnection使用方法與實例演示分析
這篇文章主要介紹了Java?HttpURLConnection使用方法與實例演示,HttpURLConnection一個抽象類是標準的JAVA接口,該類位于java.net包中,它提供了基本的URL請求,響應等功能,下面我們來深入看看2023-10-10