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实例创建及构造器挑选内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Druid核心源码解析DruidDataSource

    Druid核心源码解析DruidDataSource

    这篇文章主要为大家介绍了Druid核心源码解析DruidDataSource,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • log4j中logger标签中additivity属性的用法说明

    log4j中logger标签中additivity属性的用法说明

    这篇文章主要介绍了log4j中logger标签中additivity属性的用法说明,基于很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • idea运行java项目main方法报build failure错误的解决方法

    idea运行java项目main方法报build failure错误的解决方法

    当在使用 IntelliJ IDEA 运行 Java 项目的 main 方法时遇到 "Build Failure" 错误,这通常意味着在项目的构建过程中遇到了问题,以下是一些详细的解决步骤,以及一个简单的代码示例,用于展示如何确保 Java 程序可以成功构建和运行,需要的朋友可以参考下
    2024-09-09
  • Java并发Futures和Callables类实例详解

    Java并发Futures和Callables类实例详解

    Callable对象返回Future对象,该对象提供监视线程执行的任务进度的方法, Future对象可用于检查Callable的状态,然后线程完成后从Callable中检索结果,这篇文章给大家介绍Java并发Futures和Callables类的相关知识,感兴趣的朋友一起看看吧
    2024-05-05
  • Java使用@EnableEurekaServer实现自动装配详解

    Java使用@EnableEurekaServer实现自动装配详解

    这篇文章主要介绍了Java使用@EnableEurekaServer实现自动装配过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-10-10
  • gateway网关与前端请求跨域问题的解决方案

    gateway网关与前端请求跨域问题的解决方案

    这篇文章主要介绍了gateway网关与前端请求跨域问题的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Java使用Arrays.asList报UnsupportedOperationException的解决

    Java使用Arrays.asList报UnsupportedOperationException的解决

    这篇文章主要介绍了Java使用Arrays.asList报UnsupportedOperationException的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 你知道Java的这些骚操作吗?

    你知道Java的这些骚操作吗?

    今天在看python相关的东西,看到各种骚操作,回头想了下Java有没有什么骚操作,整理下面几种,一起看一下吧,需要的朋友可以参考下
    2021-05-05
  • 快速排序的深入详解以及java实现

    快速排序的深入详解以及java实现

    本篇文章是对java中的快速排序进行了详细的分析介绍,需要的朋友参考下
    2013-07-07
  • java.text.DecimalFormat类十进制格式化

    java.text.DecimalFormat类十进制格式化

    这篇文章主要为大家详细介绍了java.text.DecimalFormat类十进制格式化的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03

最新评论