Spring-Ioc之bean注入-singleton

Spring-Ioc之bean注入-singleton

大家知道spring-ioc的bean注入是其核心模块。其中包括了beanDefinition的创建,bean的生命周期,特殊情况的bean-aop。最终形成的bean会有不同的scope熟悉。这里就先详细分析一下singleton-scope情况下,bean是如何通过spring的反射机制来实现注入的。

代码版本

spring 5.0.8
jdk 1.8

源码片段

这里会贴出进行本次分析的源码片段

1.启动类的main方法
public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.register(ConfigTest.class);
        ctx.refresh();
        BeanTest beanTest = ctx.getBean(BeanTest.class);
        String name = beanTest.getName();
        System.out.println(name);
    }
2.简单bean
public class BeanTest {

    private int age;

    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
3.简单配置类
@Configuration
public class ConfigTest {

    @Bean
    public BeanTest getBeanTest(){
        BeanTest beanTest = new BeanTest();
        beanTest.setName("ok");
        return beanTest;
    }
}

分析目的

了解一个最简单单例bean的实例化过程

分析步骤

  1. 调用链图解
  2. 核心代码分析
调用链图解

Spring-Ioc之bean注入-singleton_第1张图片

序号 作用 方法 方法执行行数
1 AbstractApplicationContext refresh() 549 finishBeanFactoryInitialization(beanFactory);
2 AbstractApplicationContext finishBeanFactoryInitialization(…) 868 beanFactory.preInstantiateSingletons()
3 DefaultListableBeanFactory preInstantiateSingletons() 758 getBean(beanName);
4 AbstractBeanFactory doGetBean(…) 315 sharedInstance = getSingleton(beanName, () -> {
5 DefaultSingletonBeanRegistry getSingleton(…) 222 singletonObject = singletonFactory.getObject();
6 这里根据不同的scope执行不同的处理代码 AbstractBeanFactory doGetBean(…) 317 return createBean(beanName, mbd, args);
7 AbstractAutowireCapableBeanFactory createBean(…) 495 Object beanInstance = doCreateBean(beanName, mbdToUse, args);
8 AbstractAutowireCapableBeanFactory doCreateBean(…) 535 instanceWrapper = createBeanInstance(beanName, mbd, args);
9 AbstractAutowireCapableBeanFactory createBeanInstance(…) 1095 if (mbd.getFactoryMethodName() != null) {
10 AbstractAutowireCapableBeanFactory instantiateUsingFactoryMethod(…) 1247 return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
11 通过参数匹配找到并执行工厂方法 ConstructorResolver instantiateUsingFactoryMethod(…) 581 beanInstance = this.beanFactory.getInstantiationStrategy().instantiate
12 这个方法是创建bean对象,最终执行反射的地方 SimpleInstantiationStrategy instantiate
核心代码分析

SimpleInstantiationStrategy.instantiate

public class SimpleInstantiationStrategy implements InstantiationStrategy {

...

//这个方法是创建bean对象,最终执行反射的地方。
//部分参数说明
//beanName getBeanTest
//factoryBean {ConfigTest$$EnhancerBySpringCGLIB$$b5d90a6e}注意这里,所有@Configuration类在启动时都使用CGLIB进行子类化
//factoryMethod public com.kaxudodo.demo.BeanTest com.kaxudodo.demo.ConfigTest.getBeanTest()
@Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
			@Nullable Object factoryBean, final Method factoryMethod, @Nullable Object... args) {

		try {
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					ReflectionUtils.makeAccessible(factoryMethod);
					return null;
				});
			}
			else {
				//使给定方法可访问,必要时明确设置它可访问。 
				ReflectionUtils.makeAccessible(factoryMethod);
			}
			//这里获取为空
			Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
			try {
				
				//将方法对象放入当前 ThreadLocal currentlyInvokedFactoryMethod
				currentlyInvokedFactoryMethod.set(factoryMethod);
				//通过反射生成对象bean
				Object result = factoryMethod.invoke(factoryBean, args);
				if (result == null) {
					result = new NullBean();
				}
				return result;
			}
			finally {
				if (priorInvokedFactoryMethod != null) {
					currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
				}
				else {
					//从currentlyInvokedFactoryMethod中删除方法对象
					currentlyInvokedFactoryMethod.remove();
				}
			}
		}
		catch (IllegalArgumentException ex) {
			throw new BeanInstantiationException(factoryMethod,
					"Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +
					"args: " + StringUtils.arrayToCommaDelimitedString(args), ex);
		}
		catch (IllegalAccessException ex) {
			throw new BeanInstantiationException(factoryMethod,
					"Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex);
		}
		catch (InvocationTargetException ex) {
			String msg = "Factory method '" + factoryMethod.getName() + "' threw exception";
			if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
					((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {
				msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
						"declaring the factory method as static for independence from its containing instance. " + msg;
			}
			throw new BeanInstantiationException(factoryMethod, msg, ex.getTargetException());
		}
	}

ConstructorResolver.instantiateUsingFactoryMethod

//代理解决构造函数和工厂方法。通过参数匹配执行构造函数解析。
class ConstructorResolver {

...

//使用命名的工厂方法来声明bean。
public BeanWrapper instantiateUsingFactoryMethod(
			final String beanName, final RootBeanDefinition mbd, @Nullable final Object[] explicitArgs) {

		//BeanWrapperImpl是个bean包装对象。默认的BeanWrapper实现应该足以满足所有典型用例。 为了提升效率,缓存内省结果。这里不展开,关于缓存内省结果可以计划另开一篇博文
		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);

		Object factoryBean;
		Class<?> factoryClass;
		boolean isStatic;

		String factoryBeanName = mbd.getFactoryBeanName();
		//这里判断是否是静态工厂方法,如果存在工厂beanName则不是
		//这里的factoryBeanName值为"configTest"
		if (factoryBeanName != null) {
			if (factoryBeanName.equals(beanName)) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"factory-bean reference points back to the same bean definition");
			}
			factoryBean = this.beanFactory.getBean(factoryBeanName);
			if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
				throw new ImplicitlyAppearedSingletonException();
			}
			factoryClass = factoryBean.getClass();
			isStatic = false;
		}
		else {
			// It's a static factory method on the bean class.
			// 这里是静态工厂方法
			if (!mbd.hasBeanClass()) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"bean definition declares neither a bean class nor a factory-bean reference");
			}
			factoryBean = null;
			factoryClass = mbd.getBeanClass();
			isStatic = true;
		}
		//无论是静态或者非静态,上述代码都将找出工厂方法对于的工厂类(factoryClass)

		Method factoryMethodToUse = null;
		ArgumentsHolder argsHolderToUse = null;
		Object[] argsToUse = null;
		
		//这里判断工厂方法是否有传入参数,本例是null
		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			Object[] argsToResolve = null;
			synchronized (mbd.constructorArgumentLock) {
				//从mbd里面找是否有已经处理过的构造或者工厂方法,本例这里同样为空
				factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
				if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
					// Found a cached factory method...
					argsToUse = mbd.resolvedConstructorArguments;
					if (argsToUse == null) {
						argsToResolve = mbd.preparedConstructorArguments;
					}
				}
			}
			if (argsToResolve != null) {
				argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
			}
		}

		//到这里factoryMethodToUse还是为null,会进入这个if块,获取最终的factoryMethodToUse
		if (factoryMethodToUse == null || argsToUse == null) {
			// Need to determine the factory method...
			// Try all methods with this name to see if they match the given arguments.
			//执行这行代码之前factoryClass还是被spring代理的代理工厂类 class ConfigTest$$EnhancerBySpringCGLIB$$cc75d322
			factoryClass = ClassUtils.getUserClass(factoryClass);
			//执行以后通过ClassUtils.getUserClass找到了代理类的父类 class ConfigTest

			//这一段代码获取候选工厂方法,并进行排序(sortFactoryMethods),首选公共方法,使用最多参数的“贪婪”方法。
			Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
			List<Method> candidateSet = new ArrayList<>();
			for (Method candidate : rawCandidates) {
				if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
					candidateSet.add(candidate);
				}
			}
			Method[] candidates = candidateSet.toArray(new Method[0]);
			AutowireUtils.sortFactoryMethods(candidates);

			ConstructorArgumentValues resolvedValues = null;
			boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
			int minTypeDiffWeight = Integer.MAX_VALUE;
			Set<Method> ambiguousFactoryMethods = null;

			int minNrOfArgs;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
				// We don't have arguments passed in programmatically, so we need to resolve the
				// arguments specified in the constructor arguments held in the bean definition.
				//当mdb需要构造参数,而在编码过程中没有传入参数的时候,进行处理
				//本例中mdb不需要构造参数,不会进入此逻辑
				if (mbd.hasConstructorArgumentValues()) {
					ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
					resolvedValues = new ConstructorArgumentValues();
					minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
				}
				else {
					minNrOfArgs = 0;
				}
			}

			LinkedList<UnsatisfiedDependencyException> causes = null;

			for (Method candidate : candidates) {
				Class<?>[] paramTypes = candidate.getParameterTypes();

				if (paramTypes.length >= minNrOfArgs) {
					ArgumentsHolder argsHolder;
					//这段逻辑是为了得到argsHolder,分为有传入参数和无传入参数
					if (explicitArgs != null){
						// Explicit arguments given -> arguments length must match exactly.
						if (paramTypes.length != explicitArgs.length) {
							continue;
						}
						//在确保传入参数和工厂方法参数数量一致的情况下得到argsHolder 
						argsHolder = new ArgumentsHolder(explicitArgs);
					}
					else {
						// Resolved constructor arguments: type conversion and/or autowiring necessary.
						// 在无传入参数的情况下,进行必要的类型转换或自动装配
						try {
							String[] paramNames = null;
							ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
							if (pnd != null) {
								paramNames = pnd.getParameterNames(candidate);
							}
							//参数的类型转换或自动装配发生在createArgumentArray方法中,这里就不展开了
							argsHolder = createArgumentArray(
									beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
						}
						catch (UnsatisfiedDependencyException ex) {
							if (logger.isTraceEnabled()) {
								logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
							}
							// Swallow and try next overloaded factory method.
							if (causes == null) {
								causes = new LinkedList<>();
							}
							causes.add(ex);
							continue;
						}
					}

					//这一段代码通过比较argsHolder中的参数和候选方法中的参数来得到差异权重
					int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
							argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
					// Choose this factory method if it represents the closest match.
					//这里注意minTypeDiffWeight是在for循环外部定义,一旦差异权重比最小差异权重小,则更新相关属性
					//包括:将使用的工厂方法,argsHolderToUse ,argsToUse ,minTypeDiffWeight 
					if (typeDiffWeight < minTypeDiffWeight) {
						factoryMethodToUse = candidate;
						argsHolderToUse = argsHolder;
						argsToUse = argsHolder.arguments;
						minTypeDiffWeight = typeDiffWeight;
						ambiguousFactoryMethods = null;
					}
					// Find out about ambiguity: In case of the same type difference weight
					// for methods with the same number of parameters, collect such candidates
					// and eventually raise an ambiguity exception.
					// However, only perform that check in non-lenient constructor resolution mode,
					// and explicitly ignore overridden methods (with the same parameter signature).
					//通过原始注释可以了解到在非宽松的情况下将收集歧义方法,并最终抛出异常
					else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
							!mbd.isLenientConstructorResolution() &&
							paramTypes.length == factoryMethodToUse.getParameterCount() &&
							!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
						if (ambiguousFactoryMethods == null) {
							ambiguousFactoryMethods = new LinkedHashSet<>();
							ambiguousFactoryMethods.add(factoryMethodToUse);
						}
						ambiguousFactoryMethods.add(candidate);
					}
				}
			}

			//这里是各自异常出现的情况,不详细说明
			if (factoryMethodToUse == null) {
				if (causes != null) {
					UnsatisfiedDependencyException ex = causes.removeLast();
					for (Exception cause : causes) {
						this.beanFactory.onSuppressedException(cause);
					}
					throw ex;
				}
				List<String> argTypes = new ArrayList<>(minNrOfArgs);
				if (explicitArgs != null) {
					for (Object arg : explicitArgs) {
						argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
					}
				}
				else if (resolvedValues != null){
					Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
					valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
					valueHolders.addAll(resolvedValues.getGenericArgumentValues());
					for (ValueHolder value : valueHolders) {
						String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
								(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
						argTypes.add(argType);
					}
				}
				String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"No matching factory method found: " +
						(mbd.getFactoryBeanName() != null ?
							"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
						"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
						"Check that a method with the specified name " +
						(minNrOfArgs > 0 ? "and arguments " : "") +
						"exists and that it is " +
						(isStatic ? "static" : "non-static") + ".");
			}
			else if (void.class == factoryMethodToUse.getReturnType()) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Invalid factory method '" + mbd.getFactoryMethodName() +
						"': needs to have a non-void return type!");
			}
			else if (ambiguousFactoryMethods != null) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Ambiguous factory method matches found in bean '" + beanName + "' " +
						"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
						ambiguousFactoryMethods);
			}

			if (explicitArgs == null && argsHolderToUse != null) {
				argsHolderToUse.storeCache(mbd, factoryMethodToUse);
			}
		}

		try {
			Object beanInstance;

			if (System.getSecurityManager() != null) {
				final Object fb = factoryBean;
				final Method factoryMethod = factoryMethodToUse;
				final Object[] args = argsToUse;
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, beanFactory, fb, factoryMethod, args),
						beanFactory.getAccessControlContext());
			}
			//这里就进入上一个源代码的方法了,进行bean的创建
			else {
				beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
						mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
			}

			bw.setBeanInstance(beanInstance);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean instantiation via factory method failed", ex);
		}
	}

你可能感兴趣的:(java架构)