分析Spring Bean实例化代码,探究Bean是如何被Spring实例化的
一、Bean的实例化代码分析 先看下面Spring实例化bean的代码,通过参数beanName、BeanDefinition、args来实例化bean,包含以下几步:
AbstractAutowireCapableBeanFactory.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 protected BeanWrapper createBeanInstance (String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { Class<?> beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowe()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null ) { return obtainFromSupplier(instanceSupplier, beanName); } if (mbd.getFactoryMethodName() != null ) { return instantiateUsingFactoryMethod(beanName, mbd, args); } boolean resolved = false ; boolean autowireNecessary = false ; if (args == null ) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null ) { resolved = true ; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null , null ); } else { return instantiateBean(beanName, mbd); } } Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } return instantiateBean(beanName, mbd); }
无论是有参构造函数还是无参构造函数,都会寻找一个构造函数来实例化,只是有参构造函数的寻找十分复杂,下面以无参构造函数的实例化代码举例。
根据代码中instantiate()方法继续向下跟踪到BeanUtils#instantiateClass()
的方法中,可以十分明显的看到ctor.newInstance(args)方法的调用,使用反射实例化bean的本质一览无遗。AbstractAutowireCapableBeanFactory.java 1 2 3 4 protected BeanWrapper instantiateBean (final String beanName, final RootBeanDefinition mbd) {...... beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); ......
SimpleInstantiationStrategy.java 1 2 3 4 5 6 7 8 9 10 public Object instantiate (RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {...... { return BeanUtils.instantiateClass(constructorToUse); } else { return instantiateWithMethodInjection(bd, beanName, owner); } ......
BeanUtils.java 1 2 3 4 5 6 7 8 public static <T> T instantiateClass (Constructor<T> ctor, Object... args) throws BeanInstantiationException { Assert.notNull(ctor, "Constructor must not be null" ); try { ReflectionUtils.makeAccessible(ctor); return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ? KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args)); } ......
二、结论 Spring对于普通单例bean的实例化,采用的是反射调用构造函数实现的。