先说结论
- 如果只提供了一个无参的构造方法:返回 null
- 如果只提供了一个有参的构造方法:返回 1
- 如果提供了多个 @Autowired
Spring 在推断构造方法的时候,如果提供了多个合格的构造方法,会使用哪一个构造方法来创建实例呢?
public class IndexService {public IndexService(){System.out.println("IndexService using default constructor");}public IndexService(UserService userService){System.out.println("IndexService using userService constructor");}public IndexService(UserService userService, OrderService orderService){System.out.println("IndexService using userService & orderService constructor");}}
答案是,使用默认的构造方法创建实例
如果在需要的构造方法上加上了注解 @Autowired 呢
@Componentpublic class IndexService {public IndexService(){System.out.println("IndexService using default constructor");}public IndexService(UserService userService){System.out.println("IndexService using userService constructor");}@Autowiredpublic IndexService(UserService userService, OrderService orderService){System.out.println("IndexService using userService & orderService constructor");}}
答案是:很简单,既然你指定了需要注入的构造方法,我就使用你提供的构造方法
那么如果我想让 Spring 自动推断出最长参数的构造方法,除了使用 @Autowried 还有别的方法么?答案肯定是有的,那么我们就需要使用 BeanFactoryPostProcessor 了,利用他改变 AutowireMode 模型为 AUTOWIRE_CONSTRUCTOR,此时就能自动使用参数最长的构造方法了
@Componentpublic class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {GenericBeanDefinition bd = (GenericBeanDefinition) beanFactory.getBeanDefinition("indexService");bd.setAutowireMode(GenericBeanDefinition.AUTOWIRE_CONSTRUCTOR);}}
Spring 是如果推断构造方法的
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {// 再次进行推断,并确定使用哪一个构造方法,并注入return autowireConstructor(beanName, mbd, ctors, args);}
开始推断构造方法:处理实现了 SmartInstantiationAwareBeanPostProcessor 接口的后置处理器 AutowiredAnnotationBeanPostProcessor
1、提供了一个构造方法,是无参构造方法:
ctors == null
2、提供了一个构造方法,不是无参构造方法:
ctors = 1,会使用提供的构造方法,因为可以只能使用这个构造方法
3、提供了多个合格的构造方法,包括无参构造方法:
ctors == null,会调用无参构造方法,因为 spring 不知道应该利用那个构造方法装配
4、提供了多个合格的构造方法,不含无参构造方法,且都没有将其标明 @Autowired,且注入模式是 no:
ctors == null,然后抛出异常:No default constructor found
5、提供了多个合格的构造方法,不含无参构造方法,且都没有将其标明 @Autowired,且注入模式是 byConstructor:
ctors == null,找到参数值最长的合理的构造方法
6、提供了多个合格的构造方法,不含无参构造方法,且都将其标明 @Autowired(required=false):
ctors != null,找到参数值最长的合理的构造方法
7、提供了多个合格的构造方法,至少有一个标明了 @Autowired(required=false)
ctors != null,会继续推断使用哪一个构造方法,通常为第一个解析到的构造方法(这里会参数长度排序)
8、提供了多个合格的构造方法,至少有一个标明了 @Autowired(required=true) 和 @Autowired(required=false)
直接报异常:Invalid autowire-marked constructor
文字不写了,看注释…
@Override@Nullablepublic Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)throws BeanCreationException {// Let's check for lookup methods here...// 是否检查过 lookup 方法if (!this.lookupMethodsChecked.contains(beanName)) {try {ReflectionUtils.doWithMethods(beanClass, method -> {Lookup lookup = method.getAnnotation(Lookup.class);if (lookup != null) {Assert.state(this.beanFactory != null, "No BeanFactory available");LookupOverride override = new LookupOverride(method, lookup.value());try {RootBeanDefinition mbd = (RootBeanDefinition)this.beanFactory.getMergedBeanDefinition(beanName);mbd.getMethodOverrides().addOverride(override);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(beanName,"Cannot apply @Lookup to beans without corresponding bean definition");}}});}catch (IllegalStateException ex) {throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);}this.lookupMethodsChecked.add(beanName);}// Quick check on the concurrent map first, with minimal locking.// ★ candidateConstructorsCache:存放已经被推断完成的类和该类被推断出来的构造方法的集合// 检查当前的类是否在 candidateConstructorsCache 中已经存在了已经推断过的构造方法,如果被推断过,就直接拿出来使用Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);if (candidateConstructors == null) {// Fully synchronized resolution now...synchronized (this.candidateConstructorsCache) {candidateConstructors = this.candidateConstructorsCache.get(beanClass);if (candidateConstructors == null) {Constructor<?>[] rawCandidates;try {// 拿到所有的构造方法rawCandidates = beanClass.getDeclaredConstructors();}catch (Throwable ex) {throw new BeanCreationException(beanName,"Resolution of declared constructors on bean Class [" + beanClass.getName() +"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);}// 存放合格的构造方法,但是合格,并不代表都可用List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);// 必要的构造方法,比如在构造方法上加 @AutowiredConstructor<?> requiredConstructor = null;// 默认无参构造方法Constructor<?> defaultConstructor = null;// 推断主要的构造方法委托给 Kotlin,如果对于 Java 类,永远返回 nullConstructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);// 定义一个变量记录非合成的构造方法int nonSyntheticConstructors = 0;for (Constructor<?> candidate : rawCandidates) {if (!candidate.isSynthetic()) {nonSyntheticConstructors++;}else if (primaryConstructor != null) {continue;}// 检查构造方法上有没有 @Autowired 注解,并拿出 注解上的 属性AnnotationAttributes ann = findAutowiredAnnotation(candidate);// 没有 @Autowired 注解的情况if (ann == null) {// 看看 beanClass 是否是 CGLIB 代理类,并且是否有父类Class<?> userClass = ClassUtils.getUserClass(beanClass);if (userClass != beanClass) {try {Constructor<?> superCtor =userClass.getDeclaredConstructor(candidate.getParameterTypes());ann = findAutowiredAnnotation(superCtor);}catch (NoSuchMethodException ex) {// Simply proceed, no equivalent superclass constructor found...}}}// 有 @Autowired 注解的情况if (ann != null) {// 有注解,并且 @Autowired(required=true),但是第一次肯定等于 nullif (requiredConstructor != null) {throw new BeanCreationException(beanName,"Invalid autowire-marked constructor: " + candidate +". Found constructor with 'required' Autowired annotation already: " +requiredConstructor);}// 推断注解上的值,也就是 required 的值boolean required = determineRequiredStatus(ann);if (required) {// 循环构造方法,如果发现多个 @Autowired 的构造方法,就会抛出异常if (!candidates.isEmpty()) {throw new BeanCreationException(beanName,"Invalid autowire-marked constructors: " + candidates +". Found constructor with 'required' Autowired annotation: " +candidate);}// 给 requiredConstructor 赋值为 找到的构造方法requiredConstructor = candidate;}// 将构造方法放到 candidates 集合中candidates.add(candidate);}// 构造方法没有任何参数,说明是默认构造方法else if (candidate.getParameterCount() == 0) {defaultConstructor = candidate;}}if (!candidates.isEmpty()) {// Add default constructor to list of optional constructors, as fallback.if (requiredConstructor == null) {if (defaultConstructor != null) {candidates.add(defaultConstructor);}else if (candidates.size() == 1 && logger.isInfoEnabled()) {logger.info("Inconsistent constructor declaration on bean with name '" + beanName +"': single autowire-marked constructor flagged as optional - " +"this constructor is effectively required since there is no " +"default constructor to fall back to: " + candidates.get(0));}}// 推断多个构造方法candidateConstructors = candidates.toArray(new Constructor<?>[0]);}// 只提供了一个构造方法,并且是含参的else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {candidateConstructors = new Constructor<?>[] {rawCandidates[0]};}// 不会执行:primaryConstructor != null 是与 kotlin 相关,else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};}// 不会执行:primaryConstructor != null 是与 kotlin 相关else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {candidateConstructors = new Constructor<?>[] {primaryConstructor};}// 其他的情况,返回一个空集合else {candidateConstructors = new Constructor<?>[0];}// 将推断出来的构造方法存起来this.candidateConstructorsCache.put(beanClass, candidateConstructors);}}}// 返回多个构造方法的情况是:有多个 @Autowired(required=false),才会成立return (candidateConstructors.length > 0 ? candidateConstructors : null);}
