Spring Bean实例的创建及构造器的挑选
作者:做猪呢,最重要的是开森啦 发布时间:2021-08-02 09:35:57
一、举个栗子
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
//@Bean 如果不知道name,默认bean的name为方法名,下面等同于@Bean("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, RootBeanDefinition 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);
}
//@Autowired
public SetterBean(BeanService beanService, BeanService beanService1) {
bs = beanService;
System.out.println("有参构造:" + bs + "--------" + beanService1);
}
}
3.4 有多个有参构造器,指定有参构造
可以通过
像3.2 中,把@Autowired注释打开,就会使用该有参构造创建实例,启动就不会报异常,@Autowired
来指定有参构造来创建实例
四、createBeanInstance功能简介
这个方法主要是挑选构造器,然后创建实例的
依次判断使用哪种方式创建实例
有参构造是否已经解析过,解析过就从缓存中拿解析过的构造器去创建
没有解析缓存过,则通过后置处理器去获取构造器,参数如果需要注入,则autowireConstructor去注入参数,然后创建实例
都不符合的话就拿默认的无参构造器去创建实例
来源:https://blog.csdn.net/weixin_43901882/article/details/115803878


猜你喜欢
- 在Flutter中实现整个App变为灰色是非常简单的,只需要在最外层的控件上包裹ColorFiltered,用法如下:@overrideWi
- 前言本来没有计划这一篇文章的,只是在看完SpringBoot核心原理后,突然想到之前开发中遇到的MVC自动失效的问题,虽然网上有很多文章以及
- 添加POM依赖:<!-- spring-boot-监控--><dependency> <group
- 本文实例为大家分享了RecyclerView实现横向滚动效果的具体代码,供大家参考,具体内容如下布局文件<LinearLayout
- 1、相差秒public double DiffSeconds(DateTime startTime,DateTime endTime){ &
- 前言有些朋友可能是从事开发工作的时间不是特别的长,所以觉得Service相对与另外两个组件activity、broadcast receiv
- 1、maven是什么,为什么存在?项目结构是什么样子,怎么定位jar官方网站说了好多,整的多复杂一样,简单说:maven是一个管理包的工具。
- 简介官方API文档Scaffold的of方法说明有说明调用Scaffold.of方法是在Scallfold的子组件的Build方法中,也就是
- 本文以一个asp.net程序为例讲述了Repeater中添加按钮实现点击按钮获取某一行数据的方法,分享给大家供大家参考借鉴之用。具体步骤如下
- 本文实例分析了C#动态生成DropDownList执行失败原因。分享给大家供大家参考。具体如下:今天研究DDL控件的动态生成的时候遇到了点问
- Java设计模式的模板方法模式定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义该算法中的某些特定步
- 本文实例为大家分享了JAVA实现人脸识别的具体代码,供大家参考,具体内容如下官方下载 安装文件 ,以win7为例,下载opencv-2.4.
- 一、 springBoot + Mybatis配置完成后,访问数据库遇到的问题首先出现这个问题,肯定是xml文件与mapper接口没有匹配上
- 问题描述设有n个会议的集合C={1,2,…,n},其中每个会议都要求使用同一个资源(如会议室),而在同一时间内只能有一
- springmvc的图片上传1.导入相应的pom依赖 <dependency> <groupId>co
- clone() 方法麻烦一些,需要将所有涉及到的类实现声明式接口 Cloneable,并覆盖Object类中的clone()方法,并设置作用
- 1.类加载机制Java中的源码.java后缀文件会在运行前被编译成.class后缀文件,文件内的字节码的本质就是一个字节数组 ,它有特定的复
- 互连网早期的时候,主机间的互连使用的是NCP协议。这种协议本身有很多缺陷,如:不能互连不同的主机,不能互连不同的操作系统,没有纠错功能。为了
- 前言:在 Java 中,让线程休眠的方法有很多,这些方法大致可以分为两类,一类是设置时间,在一段时间后自动唤醒,而另一个类是提供了一对休眠和
- 本文实例为大家分享了unity通过Mesh网格绘制球体的具体代码,供大家参考,具体内容如下接着上一篇文章说:球体public class 球