Spring Bean实例的创建及构造器的挑选

 更新时间:2021年04月20日 14:05:34   作者:做猪呢,最重要的是开森啦  
这篇文章主要介绍了Spring Bean实例的创建及构造器的挑选,文中有非常详细的代码示例,对正在学习java的小伙伴们有很好的帮助,需要的朋友可以参考下

一、举个栗子

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 有多个有参构造器,指定有参构造

可以通过@Autowired来指定有参构造来创建实例

像3.2 中,把@Autowired注释打开,就会使用该有参构造创建实例,启动就不会报异常,

四、createBeanInstance功能简介

这个方法主要是挑选构造器,然后创建实例的

  • 依次判断使用哪种方式创建实例
  • 有参构造是否已经解析过,解析过就从缓存中拿解析过的构造器去创建
  • 没有解析缓存过,则通过后置处理器去获取构造器,参数如果需要注入,则autowireConstructor去注入参数,然后创建实例
  • 都不符合的话就拿默认的无参构造器去创建实例

到此这篇关于Spring Bean实例的创建及构造器的挑选的文章就介绍到这了,更多相关Bean实例创建及构造器挑选内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Knife4j的请求示例当中有很多空白行的问题解决办法

    Knife4j的请求示例当中有很多空白行的问题解决办法

    这篇文章主要介绍了Knife4j的请求示例当中有很多空白行的问题解决办法,按正常来说不应该有上方的空白,当然如果只是查看我也不至于非要解决他,主要是假如接口是json传参,调试界面都没办法修改参数,遇到同样问题的同学可以参考阅读本文
    2024-09-09
  • Java动态规划之丑数问题实例讲解

    Java动态规划之丑数问题实例讲解

    这篇文章主要介绍了Java动态规划之丑数问题实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09
  • Java基于Graphics2D实现海报制作

    Java基于Graphics2D实现海报制作

    这篇文章主要为大家详细介绍了Java如何基于Graphics2D实现海报制作,并且支持自定义颜色,背景,logo,贴图,感兴趣的小伙伴可以了解一下
    2024-04-04
  • SpringBoot实现动态配置及项目打包部署上线功能

    SpringBoot实现动态配置及项目打包部署上线功能

    本文讲解的是如何使用Spring动态配置文件,实现不同环境不同配置,灵活切换配置文件;以及讲述了如何使用 Maven 打包,然后上传至Linux服务器进行部署,对SpringBoot打包部署上线过程感兴趣的朋友一起看看吧
    2022-10-10
  • Mybatis plus中的like查询问题

    Mybatis plus中的like查询问题

    这篇文章主要介绍了Mybatis plus中的like查询问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • 快速上手Mybatis-plus结构构建过程

    快速上手Mybatis-plus结构构建过程

    这篇文章主要介绍了快速上手Mybatis-plus结构构建过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • java简单插入排序实例

    java简单插入排序实例

    这篇文章主要为大家详细介绍了java简单插入排序实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • 最全Gson使用

    最全Gson使用

    GSON弥补了JSON的许多不足的地方,在实际应用中更加适用于Java开发,本文主要介绍了最全Gson使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • 删除JAVA集合中元素的实现代码

    删除JAVA集合中元素的实现代码

    有时候我们要删除集合中的某些元素,那么就可以参考下面的代码
    2013-07-07
  • Redisson可重入锁解锁逻辑详细讲解

    Redisson可重入锁解锁逻辑详细讲解

    Redisson开源框架是一个Redis的分布式锁的现成实现方案,是Redis的java实现的客户端。通过Netty支持非阻塞I/O。Redisson实现了分布式锁的自动续期机制、锁的互斥自等待机制、锁的可重入加锁与释放锁的机制
    2023-02-02

最新评论