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

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

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

做猪呢,最重要的是开森啦   2021-04-20 我要评论
想了解Spring Bean实例的创建及构造器的挑选的相关内容吗,做猪呢,最重要的是开森啦在本文为您仔细讲解Spring Bean实例创建及构造器挑选的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:Spring,Bean实例创建及构造器挑选,java创建实例,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去注入参数,然后创建实例
  • 都不符合的话就拿默认的无参构造器去创建实例

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们