作者:红箭777_387 | 来源:互联网 | 2023-08-11 19:08
一、举个栗子publicclassBeanServiceImplimplementsBeanService{}@ConfigurationpublicclassConfigurat
文章目录[隐藏] - 一、举个栗子
- 二、创建实例的方式
- 三、反射构造器结论现象
一、举个栗子
public class BeanServiceImpl implements BeanService {
}
@Configuration
public class ConfigurationBean {
@Bean
public BeanService beanService() {
BeanServiceImpl beanService = new BeanServiceImpl();
System.out.println("beanService: " + beanService);
return beanService;
}
@Bean
[email protected] 如果不知道name,默认bean的name为方法名,[email protected]("beanService1")
public BeanService beanService1() {
BeanServiceImpl beanService1 = new BeanServiceImpl();
System.out.println("beanService1: " + beanService1);
return beanService1;
}
}
@Component
public class SetterBean {
private BeanService bs;
public SetterBean(BeanService beanService) {
bs = beanService;
System.out.println("有参构造:" + bs);
}
}
二、创建实例的方式
- 通过Supplier的回调方法去创建
- 通过工厂方法去创建通过
- 反射构造器去创建
绝大部分是通过反射构造器去创建,详情源码见AbstractAutowireCapableBeanFactory.doCreateBean
中的createBeanInstance
方法
三、反射构造器结论现象
3.1 没有有参构造器
如果没有有参构造器,默认使用无参的构造方法反射创建实例,详情见createBeanInstance ? instantiateBean
方法
protected BeanWrapper createBeanInstance(String beanName, RootBea本文来源gao@.dai.ma.com搞@^&[email protected])网9nDefinition mbd, @Nullable Object[] args) {
... ...
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
3.2 有唯一的有参构造器
如果有唯一有参构造器,并且参数能在Spring容器里找到,则通过该有参构造器反射创建
详情见createBeanInstance ? autowireConstructor
方法
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
... ...
// Candidate constructors for autowiring?
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
... ...
}
如果参数不能在Spring容器中找到,就会报NoUniqueBeanDefinitionException
异常
3.3 有多个有参构造器,不指定构造器
有多个有参构造器,Spring在创建Bean实例时,就不知道用哪个构造器去创建,就会报如下异常:
BeanInstantiationException: Failed to instantiate [XXX]: No default constructor found;
@Component
public class SetterBean {
private BeanService bs;
public SetterBean(BeanService beanService) {
bs = beanService;
System.out.println("有参构造:" + bs);
}
[email protected]
public SetterBean(BeanService beanService, BeanService beanService1) {
bs = beanService;
System.out.println("有参构造:" + bs + "--------" + beanService1);
}
}
3.4 有多个有参构造器,指定有参构造