Spring依赖注入之@Autowired、@Qualifier、@Primary、@Priority注解原理(上)

@Autowired注解可以声明一个bean依赖的其他bean,spring在创建bean时会将这些依赖的bean注入进来,涉及到的注解有@Autowired、@Value、@Qualifier、@Primary、@Priority几个注解。@Autowired注解可以使用在Field、Constructor、Method上来注入依赖,本质上只是使用地方不同,最终都会通过AutowireCapableBeanFactory#resolveDependency方法解析出依赖的实例。本节分析标注在Field、Constructor、Method上的@Autowired注解是如何起作用的

1、Field&Method上的@Autowired注解

Field和Method上的@Autowired注解都是在bean实例化之后,通过AutowiredAnnotationBeanPostProcessor#postProcessProperties方法进行注入的。这个方法中首先回解析出所有带有@Autowired的Field和Method,然后分别进行注入,如下

	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
			metadata.inject(bean, beanName, pvs);
		}
		catch (BeanCreationException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
		}
		return pvs;
	}

InjectionMetadata就是包装了将要注入依赖的targetClass和要注入以来的对象InjectedElement,就是Field或Method

public class InjectionMetadata {
    
	private final Class<?> targetClass;

	private final Collection<InjectedElement> injectedElements;
}

InjectedElement是要注入的目标,member是Constructor、Method、Field的父类,isField标识是否是Field

	public abstract static class InjectedElement {

		protected final Member member;

		protected final boolean isField;
    }

InjectedElement有两个子类,AutowiredFieldElement和AutowiredMethodElement,required即@Autowired注解的required字段;cached、cachedFieldValue、cachedMethodArguments涉及缓存逻辑

	private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {

		private final boolean required;

		private volatile boolean cached;

		@Nullable
		private volatile Object cachedFieldValue;
    }
	private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {

		private final boolean required;

		private volatile boolean cached;

		@Nullable
		private volatile Object[] cachedMethodArguments;
    }

a、注解的解析

findAutowiringMetadata方法中处理了缓存逻辑,然后调用buildAutowiringMetadata真正去解析@Autowired注解

	private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
		if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
			return InjectionMetadata.EMPTY;
		}

		List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
			final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

			ReflectionUtils.doWithLocalFields(targetClass, field -> {
				MergedAnnotation<?> ann = findAutowiredAnnotation(field);
				if (ann != null) {
					if (Modifier.isStatic(field.getModifiers())) {
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation is not supported on static fields: " + field);
						}
						return;
					}
					boolean required = determineRequiredStatus(ann);
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});

			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
				if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
					return;
				}
				MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
				if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
					if (Modifier.isStatic(method.getModifiers())) {
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation is not supported on static methods: " + method);
						}
						return;
					}
					if (method.getParameterCount() == 0) {
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation should only be used on methods with parameters: " +
									method);
						}
					}
					boolean required = determineRequiredStatus(ann);
					PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
					currElements.add(new AutowiredMethodElement(method, required, pd));
				}
			});

			elements.addAll(0, currElements);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);

		return InjectionMetadata.forElements(elements, clazz);
	}

Field依赖解析

buildAutowiringMetadata的do-while大循环里遍历targetClass及所有父类,解析其中的Field和Method,然后将解析结果包装成InjectionMetadata返回。
解析Field时,其逻辑比较简单,通过findAutowiredAnnotation解析每一个Field上的注解,会查找三个注解

  • @Autowired
  • @Value
  • @Inject

如果存在的话,再解析一下required字段

Method依赖解析

解析Method时,总体逻辑跟Field类似,通过findAutowiredAnnotation解析每一个Meathod上的注解,同样也会查找@Autowired、@Value、@Inject三个注解,然后解析required字段。解析方法时,没有对方法名做任何假设,setter方法只是其中一个特例,@Autowired方法可以不是setter。最终将Field、Method解析结果放到InjectionMetadata一起返回。
方法的解析,由于存在方法的重写、接口默认方法、桥接方法,要考虑的问题要复杂很多。

具体遍历哪些方法
	private static Method[] getDeclaredMethods(Class<?> clazz, boolean defensive) {
		Assert.notNull(clazz, "Class must not be null");
		Method[] result = declaredMethodsCache.get(clazz);
		if (result == null) {
			try {
				Method[] declaredMethods = clazz.getDeclaredMethods();
				List<Method> defaultMethods = findConcreteMethodsOnInterfaces(clazz);
				if (defaultMethods != null) {
					result = new Method[declaredMethods.length + defaultMethods.size()];
					System.arraycopy(declaredMethods, 0, result, 0, declaredMethods.length);
					int index = declaredMethods.length;
					for (Method defaultMethod : defaultMethods) {
						result[index] = defaultMethod;
						index++;
					}
				}
				else {
					result = declaredMethods;
				}
				declaredMethodsCache.put(clazz, (result.length == 0 ? EMPTY_METHOD_ARRAY : result));
			}
			catch (Throwable ex) {
				throw new IllegalStateException("Failed to introspect Class [" + clazz.getName() +
						"] from ClassLoader [" + clazz.getClassLoader() + "]", ex);
			}
		}
		return (result.length == 0 || !defensive) ? result : result.clone();
	}

doWithLocalMethods方法会遍历这个类的declaredMethod和这个类的所有接口的默认方法。

bridge方法的处理

BridgeMethodResolver#findBridgedMethod找到当前方法的被bridge的方法,如果当前方法不是bridge方法,则返回这个方法本身。
BridgeMethodResolver#isVisibilityBridgeMethodPair会过滤掉bridge方法

	public static boolean isVisibilityBridgeMethodPair(Method bridgeMethod, Method bridgedMethod) {
		if (bridgeMethod == bridgedMethod) {
			return true;
		}
		return (bridgeMethod.getReturnType().equals(bridgedMethod.getReturnType()) &&
				bridgeMethod.getParameterCount() == bridgedMethod.getParameterCount() &&
				Arrays.equals(bridgeMethod.getParameterTypes(), bridgedMethod.getParameterTypes()));
	}

这里应当是有三种情况:

  • 如果bridgeMethod是一个普通方法(不是bridge方法),那么bridgeMethod==bridgedMethod,返回true,外部需要处理这个方法
  • 如果bridgeMethod是一个bridge方法,但是是由于可见性问题引入的bridge方法,返回true,外部来解析这个bridge方法(后续依赖注入时也会调用这个bridge方法,是因为直接调用原方法的话会由于无法访问抛出异常)
  • 如果bridgeMethod是一个bridge方法,但是是由于方法重写(重写时修改了返回类型、子类将泛型具体化)引入的桥接方法,那么返回false,外部不要处理这个方法,而是去处理这个方法的被桥接的方法

bridge方法这里解释的不够,后面专门讲bridge方法

方法重写的处理

当子类重写了父类方法,依赖的解析应当忽略父类方法而解析子类方法。但是doWithLocalMethods会遍历父类的所有方法,遍历到父类方法是如何知道应当忽略的呢?

if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz)))

当这个方法存在依赖注入注解并且method.equals(ClassUtils.getMostSpecificMethod(method, clazz))才会去处理这个方法。ClassUtils#getMostSpecificMethod这个方法会顺着类继承层次从clazz开始往上找一个同名同参方法,如果method和这个同名同参方法相等,说明这个方法没有被重写,是需要处理的。

b、依赖注入

postProcessProperties方法中,先解析出来InjectionMetadata后,调用InjectionMetadata#inject完成对Field、Method的注入。

	public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
		Collection<InjectedElement> checkedElements = this.checkedElements;
		Collection<InjectedElement> elementsToIterate =
				(checkedElements != null ? checkedElements : this.injectedElements);
		if (!elementsToIterate.isEmpty()) {
			for (InjectedElement element : elementsToIterate) {
				element.inject(target, beanName, pvs);
			}
		}
	}

InjectionMetadata#inject方法就是遍历了每一个element进行注入,每个element有两种情况:AutowiredFieldElement和AutowiredMethodElement。

Field的依赖注入

		protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
			Field field = (Field) this.member;
			Object value;
			if (this.cached) {
				try {
					value = resolvedCachedArgument(beanName, this.cachedFieldValue);
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Unexpected removal of target bean for cached argument -> re-resolve
					value = resolveFieldValue(field, bean, beanName);
				}
			}
			else {
				value = resolveFieldValue(field, bean, beanName);
			}
			if (value != null) {
				ReflectionUtils.makeAccessible(field);
				field.set(bean, value);
			}
		}

除去缓存逻辑之外,就是调用resolveFieldValue解析出value,如果不为null的话通过反射set进去,如果为null则不处理。这样可以设置required=false然后给一个默认值,如果不存在就为默认值。

		private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
			DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
			desc.setContainingClass(bean.getClass());
			Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
			Assert.state(beanFactory != null, "No BeanFactory available");
			TypeConverter typeConverter = beanFactory.getTypeConverter();
			Object value;
			try {
				value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
			}
			synchronized (this) {
				if (!this.cached) {
					Object cachedFieldValue = null;
					if (value != null || this.required) {
						cachedFieldValue = desc;
						registerDependentBeans(beanName, autowiredBeanNames);
						if (autowiredBeanNames.size() == 1) {
							String autowiredBeanName = autowiredBeanNames.iterator().next();
							if (beanFactory.containsBean(autowiredBeanName) &&
									beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
								cachedFieldValue = new ShortcutDependencyDescriptor(
										desc, autowiredBeanName, field.getType());
							}
						}
					}
					this.cachedFieldValue = cachedFieldValue;
					this.cached = true;
				}
			}
			return value;
		}
	}

resolveFieldValue调用AutowireCapableBeanFactory#resolveDependency解析出要注入的bean,这里面统一处理了@Autowired、@Value、@Inject三个注解,具体逻辑下节分析

Method的依赖注入

		protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
			if (checkPropertySkipping(pvs)) {
				return;
			}
			Method method = (Method) this.member;
			Object[] arguments;
			if (this.cached) {
				try {
					arguments = resolveCachedArguments(beanName);
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Unexpected removal of target bean for cached argument -> re-resolve
					arguments = resolveMethodArguments(method, bean, beanName);
				}
			}
			else {
				arguments = resolveMethodArguments(method, bean, beanName);
			}
			if (arguments != null) {
				try {
					ReflectionUtils.makeAccessible(method);
					method.invoke(bean, arguments);
				}
				catch (InvocationTargetException ex) {
					throw ex.getTargetException();
				}
			}
		}

inject方法调用resolveMethodArguments解析出每一个参数,通过反射调用这个方法。

		private Object[] resolveMethodArguments(Method method, Object bean, @Nullable String beanName) {
			int argumentCount = method.getParameterCount();
			Object[] arguments = new Object[argumentCount];
			DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
			Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);
			Assert.state(beanFactory != null, "No BeanFactory available");
			TypeConverter typeConverter = beanFactory.getTypeConverter();
			for (int i = 0; i < arguments.length; i++) {
				MethodParameter methodParam = new MethodParameter(method, i);
				DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
				currDesc.setContainingClass(bean.getClass());
				descriptors[i] = currDesc;
				try {
					Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
					if (arg == null && !this.required) {
						arguments = null;
						break;
					}
					arguments[i] = arg;
				}
				catch (BeansException ex) {
					throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
				}
			}
			synchronized (this) {
				if (!this.cached) {
					if (arguments != null) {
						DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
						registerDependentBeans(beanName, autowiredBeans);
						if (autowiredBeans.size() == argumentCount) {
							Iterator<String> it = autowiredBeans.iterator();
							Class<?>[] paramTypes = method.getParameterTypes();
							for (int i = 0; i < paramTypes.length; i++) {
								String autowiredBeanName = it.next();
								if (beanFactory.containsBean(autowiredBeanName) &&
										beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
									cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
											descriptors[i], autowiredBeanName, paramTypes[i]);
								}
							}
						}
						this.cachedMethodArguments = cachedMethodArguments;
					}
					else {
						this.cachedMethodArguments = null;
					}
					this.cached = true;
				}
			}
			return arguments;
		}
	}

方法注入逻辑也不复杂,for循环遍历每个paramter,调用AutowireCapableBeanFactory#resolveDependency解析出每个Parameter的bean。至于Parameter上的required是如何覆盖方法上的required的,逻辑涉及到AutowireCapableBeanFactory#resolveDependency,先贴上结论后面分析:Parameter上required=false可以覆盖方法上的required=true,Parameter上required=true不能覆盖方法上的required=false,即

  • 方法上required=true,Parameter上required=false,Parameter最终的required=false
  • 方法上required=false,Parameter上required=true,Parameter最终的required=false

当参数最终required=false时,AutowireCapableBeanFactory#resolveDependency会返回null。
再看注入逻辑,方法的注入逻辑也比较特殊:

  • 如果方法required=false,有一个参数的bean不存在,全都不会注入
  • 如果方法required=true,如果参数bean不存在,则该参数注入null(即不能设置默认值了)

2、Constructor上的@Autowired注解

AbstractAutowireCapableBeanFactory在通过AbstractAutowireCapableBeanFactory#createBeanInstance方法创建bean实例时,首先会尝试通过InstanceSupplier创建,其次尝试通过FactoryMethod,再次尝试通过有参构造器来创建,最后通过无参构造器创建。
通过有参构造器方式创建时,先通过determineConstructorsFromBeanPostProcessors选择一个有参构造器出来,然后通过autowireConstructor注入以来并通过有参构造器创建对象。

		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

a、有参构造器的选择

determineConstructorsFromBeanPostProcessors遍历了InstantiationAwareBeanPostProcessor,有一个选择出Constructor就返回。最终会调用到AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors

	protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
			throws BeansException {

		if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
			for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
				Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
				if (ctors != null) {
					return ctors;
				}
			}
		}
		return null;
	}

AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors逻辑很长,总体上来说就是找到一个有依赖注入注解的构造器,如下

	public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
			throws BeanCreationException {
        // 忽略掉 Lookup逻辑
        
		// Quick check on the concurrent map first, with minimal locking.
		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);
					Constructor<?> requiredConstructor = null;
					Constructor<?> defaultConstructor = null;
					Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
					int nonSyntheticConstructors = 0;
					for (Constructor<?> candidate : rawCandidates) {
						if (!candidate.isSynthetic()) {
							nonSyntheticConstructors++;
						}
						else if (primaryConstructor != null) {
							continue;
						}
						MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
						if (ann == null) {
							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...
								}
							}
						}
						if (ann != null) {
							if (requiredConstructor != null) {
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructor: " + candidate +
										". Found constructor with 'required' Autowired annotation already: " +
										requiredConstructor);
							}
							boolean required = determineRequiredStatus(ann);
							if (required) {
								if (!candidates.isEmpty()) {
									throw new BeanCreationException(beanName,
											"Invalid autowire-marked constructors: " + candidates +
											". Found constructor with 'required' Autowired annotation: " +
											candidate);
								}
								requiredConstructor = candidate;
							}
							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]};
					}
					else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
							defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
						candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
					}
					else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
						candidateConstructors = new Constructor<?>[] {primaryConstructor};
					}
					else {
						candidateConstructors = new Constructor<?>[0];
					}
					this.candidateConstructorsCache.put(beanClass, candidateConstructors);
				}
			}
		}
		return (candidateConstructors.length > 0 ? candidateConstructors : null);
	}

for循环遍历所有的构造器,查找构造器上的依赖注入注解包括@Autowired、@Inject、@Value。由于这个类可能是CGLIB生成的,导致构造器上没有这些注解,所以还会找出UserClass,查找注解。然后处理查找结果(忽略kotlin相关逻辑)

  • 如果刚好找到一个构造器,返回
  • 如果找到多于一个构造器,抛出异常
  • 找不到构造器的情况下,如果只有这个类只有一个构造器,并且是有参构造器,返回这个有参构造器
  • 返回null

b、有参构造器注入依赖

找到有参构造器之后,就通过ConstructorResolver#autowireConstructor进行依赖注入,并实例化这个对象。ConstructorResolver#autowireConstructor代码很长,简单来说就是通过ConstructorResolver#createArgumentArray方法解析出构造器中每个参数的依赖,然后通过ConstructorResolver#instantiate方法实例化这个对象。

解析参数依赖

ConstructorResolver#createArgumentArray遍历每一个参数,首先尝试从resolvedValues找到依赖(由于autowireConstructor传过来的explicitArgs为null),所以这里找不到。然后通过ConstructorResolver#resolveAutowiredArgument方法从beanFactory里解析出依赖

	protected Object resolveAutowiredArgument(MethodParameter param, String beanName,
			@Nullable Set<String> autowiredBeanNames, TypeConverter typeConverter, boolean fallback) {

		Class<?> paramType = param.getParameterType();
		if (InjectionPoint.class.isAssignableFrom(paramType)) {
			InjectionPoint injectionPoint = currentInjectionPoint.get();
			if (injectionPoint == null) {
				throw new IllegalStateException("No current InjectionPoint available for " + param);
			}
			return injectionPoint;
		}
		try {
			return this.beanFactory.resolveDependency(
					new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
		}
		catch (NoUniqueBeanDefinitionException ex) {
			throw ex;
		}
		catch (NoSuchBeanDefinitionException ex) {
			if (fallback) {
				// Single constructor or factory method -> let's return an empty array/collection
				// for e.g. a vararg or a non-null List/Set/Map parameter.
				if (paramType.isArray()) {
					return Array.newInstance(paramType.getComponentType(), 0);
				}
				else if (CollectionFactory.isApproximableCollectionType(paramType)) {
					return CollectionFactory.createCollection(paramType, 0);
				}
				else if (CollectionFactory.isApproximableMapType(paramType)) {
					return CollectionFactory.createMap(paramType, 0);
				}
			}
			throw ex;
		}
	}

resolveAutowiredArgument也是通过beanFactory#resolveDependency解析出依赖

实例化

bean的实例化委托给了InstantiationStrategy类来创建,这个的实现分析Lookup时分析过

	private Object instantiate(
			String beanName, RootBeanDefinition mbd, Constructor<?> constructorToUse, Object[] argsToUse) {

		try {
			InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();
			if (System.getSecurityManager() != null) {
				return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse),
						this.beanFactory.getAccessControlContext());
			}
			else {
				return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean instantiation via constructor failed", ex);
		}
	}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值