1.AbstractAutowireCapableBeanFactory#createBean()主流程
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
//判断当前mbd中的class是否已经加载到jvm,如果未加载,则使用类加载器将classStr加载到Jvm中,并且返回Class对象
Class> resolvedClass = resolveBeanClass(mbd, beanName);
//条件一:拿到mbd实例化对象时的真实Class对象。
//条件二(!mbd.hasBeanClass()):条件成立,说明mbd在resolveBeanClass之前,是没有Class对象的。
//条件三:成立,说明mbd有ClassName
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 对XML标签中定义的lookUp属性进行预处理,如果只能根据名字找到一个就标记为非重载的,这样在后续就不需要去推断到底是哪个方法了,
// 对于@LookUp注解标注的方法是不需要在这里处理的,AutowiredAnnotationBeanPostProcessor会处理这个注解
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//可以通过后处理器,在这一步返回一个代理实例对象..注意,这里的代理对象不是Spring AOP 逻辑实现的地方。
//instantiation 实例化不要和init 搞混。
//后处理器调用点:创建实例之前的一个调用点。
// 它的另外一个作用就是对AOP提供了支持,在这里会将一些不需要被代理的Bean进行标记
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
//条件成立会形成一个短路操作,这里直接返回了.
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//核心方法:创建bean实例对象,并且生命周期的动作大部分都在这里
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
2.短路操作resolveBeforeInstantiation()
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
这里跟FactoryBean#getObject()会调用BeanPostProcessor#postProcessAfterInitialization()一样,也会调用这个方法,因为这里创建的bean也没有经过完整的生命周期,但是也会调用后置处理器初始化后的方法。
使用示例:
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
/**
* InstantiationAwareBeanPostProcessor中自定义的方法
* 在方法实例化之前执行 Bean对象还没有
*/
@Override
public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
System.out.println("--->postProcessBeforeInstantiation");
// 利用cglib动态代理生成对象返回
if (beanClass == Student.class) {
Enhancer e = new Enhancer();
e.setSuperclass(beanClass);
e.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("目标方法执行前:" + method);
Object object = methodProxy.invokeSuper(obj, objects);
System.out.println("目标方法执行后:" + method + "\n");
return object;
}
});
Student student = (Student) e.create();
// 返回代理类
return student;
}
return null;
}
}
配置:
结果:
目标方法执行前:public void com.wz.spring.instantiation.Student.study()
因为学习让我们相遇...
目标方法执行后:public void com.wz.spring.instantiation.Student.study()
3.AbstractAutowireCapableBeanFactory#doCreateBean主流程
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
//包装对象,内部最核心的字段就是咱们的真实实例。它提供了一些额外的接口方法,比如 属性访问器
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//该方法创建出来真实的bean实例,并且将其包装到BeanWrapper实例中。
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//后处理器调用点:合并bd信息,因为接下来就是populate处理依赖了..
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//处理当前实例的依赖数据...依赖注入在这一步完成的。
populateBean(beanName, mbd, instanceWrapper);
//生命周期中的初始化方法的调用。
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
//条件成立:说明当前bean实例 从 2级缓存获取到了...
//说明产生循环依赖了...3级缓存 当前对象的ObjectFactory.getObject() 被调用过
if (earlySingletonReference != null) {
//条件成立有几种情况?
//1.当前“真实实例”不需要被代理
//2.当前“实例”已经被代理过了...是在ObjectFactory.getObject() 方法调用时 实现的增强代理。
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
//获取依赖当前bean的 其它beanName
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
//为什么有问题?
//因为咱们当前对象的AOP操作是在 当前方法的 initializeBean 这个方法完成的。
//在这之前 外部其它bean持有到的当前的 “bean实例” 都是尚未增强的。
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
//判断当前bean实例是否需要注册 析构回调。当容器销毁时,会给当前bean的析构方法进行回调。
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
3.1 this.factoryBeanInstanceCache.remove(beanName)关于FactoryBean
// 这里申明了一个FactoryBean,并且通过@DependsOn注解申明了这个FactoryBean的创建要在orderService之后,主要目的是为了在DmzFactoryBean创建前让容器发生一次属性注入
@Component
@DependsOn("orderService")
public class DmzFactoryBean implements FactoryBean {
@Override
public DmzService getObject() throws Exception {
return new DmzService();
}
@Override
public Class> getObjectType() {
return DmzService.class;
}
}
// 没有通过注解的方式将它放到容器中,而是通过上面的DmzFactoryBean来管理对应的Bean
public class DmzService {
}
// OrderService中需要注入dmzService
@Component
public class OrderService {
@Autowired
DmzService dmzService;
}
DmzFactoryBean是依赖于orderService的,所以必定会先创建orderService再创建DmzFactoryBean。
orderService属性注入阶段:
为orderService进行属性注入可以分为这么几步
- 找到需要注入的注入点,也就是orderService中的dmzService字段
- 根据字段的类型以及名称去容器中查询符合要求的Bean
- 当遍历到一个FactroyBean时,为了确定其getObject方法返回的对象的类型需要创建这个FactroyBean(只会到对象级别),然后调用这个创建好的FactroyBean的getObjectType方法明确其类型并与注入点需要的类型比较,看是否是一个候选的Bean,在创建这个FactroyBean时就将其放入了factoryBeanInstanceCache中。
- 在确定了唯一的候选Bean之后,Spring就会对这个Bean进行创建,创建的过程又经过三个步骤
在创建对象时,因为此时factoryBeanInstanceCache已经缓存了这个Bean对应的对象,所以直接通过this.factoryBeanInstanceCache.remove(beanName)这行代码就返回了,避免了二次创建对象。
3.2 扩展点applyMergedBeanDefinitionPostProcessors()
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//后处理器调用点:合并bd信息,因为接下来就是populate处理依赖了..
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition
//做了一件事:提取出来当前beanType类型整个继承体系内的 @Autowired @Value @Inject 信息 并且包装成一个InjectionMetadata的一个
//对象,存放到 AutowiredAnnotationBeanPostProcessor 它的缓存中了,key是 beanName。
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
重点看看AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition:
AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition做了一件事:提取出来当前beanType类型整个继承体系内的 @Autowired @Value @Inject 信息 并且包装成一个InjectionMetadata的一个对象,存放到 AutowiredAnnotationBeanPostProcessor 它的缓存中了,key是 beanName。
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
private InjectionMetadata findAutowiringMetadata(String beanName, Class> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 获取当前clazz关注的@Autowired @Value @Inject注解信息
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
3.3 依赖注入populateBean()
详情请参考:https://www.jianshu.com/p/bbf51b8553d9?v=1670512502259
3.4 初始化initializeBean()
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction
3.5 注册销毁方法registerDisposableBeanIfNecessary()
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
//条件一:原型不会注册 销毁回调方法。
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
//给当前单实例注册回调适配器。 适配器内
// 根据当前bean实例是继承接口 还是 通过自定义
// 来决定具体调用哪个方法 完成销毁操作。
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
List postProcessors, @Nullable AccessControlContext acc) {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean =
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
Method destroyMethod = determineDestroyMethod(destroyMethodName);
if (destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
else {
Class>[] paramTypes = destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
}
this.destroyMethod = destroyMethod;
}
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
4.创建实例createBeanInstance()
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
//返回mbd中真实bean的Class对象。
Class> beanClass = resolveBeanClass(mbd, beanName);
//三个条件想表达的意思:bd中如果nonPublicAccessAllowed字段值为true,表示class是非公开类型的 也可以创建实例,反之false,说明是无法创建的..
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// InstanceSupplier
Supplier> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//bean标签中配置了 factory-method的情况处理
// bd中提供了factoryMethodName属性,那么要使用工厂方法的方式来创建对象,
// 工厂方法又会区分静态工厂方法跟实例工厂方法
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
//表示bd对应的构造信息是否已经解析成可以反射调用的构造方法method信息了
// 是否推断过构造方法
boolean resolved = false;
//是否自动匹配构造方法,构造方法是否需要注入(参数)
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
//条件成立:说明bd的构造信息已经转化成可以反射调用的method了
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
//当resolvedConstructorOrFactoryMethod 有值时,且构造方法有参数,那么可以认为这个字段值就是true。
//只有什么情况下这个字段是false呢?
//1.resolvedConstructorOrFactoryMethod == null
//2.当resolvedConstructorOrFactoryMethod 表示的是默认的构造方法,无参构造方法。
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
// 构造函数已经解析过了,并且这个构造函数在调用时需要自动注入参数
if (autowireNecessary) {
//有参数,那么就需要根据参数 去匹配合适的构造方法了...
//拿出当前Class的所有构造器,然后根据参数信息 去匹配出一个最优的选项,然后执行最优的 构造器 创建出实例。
// 此时部分解析好的参数已经存在了beanDefinition中,并且构造函数也在bd中
// 那么在这里只会从缓存中去取构造函数以及参数然后反射调用
return autowireConstructor(beanName, mbd, null, null);
}
else {
//无参构造方法处理
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 典型的应用:@Autowired 注解打在了 构造器方法上。参考@Autowired AutowiredAnnotationBeanPostProcessor
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
//条件一:ctors不为null:说明存在1个或多个@Autowired标注的方法。
// 再进一步选择一个差异值最小的,参数最长的构造函数
//条件二:mbd autowiredMode 一般情况是no
// 没有@Autowired标注的方法,但是需要进行自动注入,
// 那么通过autowireConstructor会去遍历类中申明的所有构造函数,
// 并查找一个差异值最小的,参数最长的构造函数
//条件三:条件成立,说明bean信息中配置了 构造参数信息。
// 说明不是自动注入,配置文件中配置了构造函数要使用的参数
//条件四:getBean时,args有参数
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
//未指定构造参数,未设定偏好...使用默认的 无参数的构造方法进行创建实例。
return instantiateBean(beanName, mbd);
}
4.1 通过factory-method创建bean
详情参见: https://www.jianshu.com/p/c9ab0026be34?v=1670424944028
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
ConstructorResolver用来解析构造函数跟工厂方法的代理者,并且它是通过参数匹配的方式来进行推断构造方法或者工厂方法。
三个参数:
- beanName:当前要实例化的Bean的名称
- mbd:当前要实例化的Bean对应的BeanDefinition
- explicitArgs:这个参数在容器启动阶段我们可以认定它就是null,只有显示的调用了getBean方法,并且传入了明确的参数,例如:getBean(“dmzService”,“hello”)这种情况下才会不为null。
4.2 通过构造方法创建bean
详情参见: https://www.jianshu.com/p/1b487205dbb6?v=1670428900594
5.factory-method跟构造函数的比较
通过构造函数实例化对象,多了一层处理,就是要处理构造函数上的@Autowired注解以及方法上的@LookUp注解(要决定选取哪一种实例化策略,SimpleInstantiationStrategy/CglibSubclassingInstantiationStrategy)。
在最终的选取也存在差异,对于facotyMehod而言,在宽松模式下(除ConfigurationClassBeanDefinition外,也就是扫描@Bean得到的BeanDefinition,都是宽松模式),会选取一个最精准的方法,在严格模式下,会选取一个参数最长的方法。
对于构造函数而言,会必定会选取一个参数最长的方法。
6.计算类型差异
集中情况说明:
- 1、factoryMethod+宽松模式:会选取一个最精确的方法,同时方法的参数要尽量长
- 2、factoryMethod+严格模式:会选取一个参数尽量长的方法
- 3、构造函数+宽松模式:会选取一个参数尽量长的方法
//typeDiffWeight 数值越高说明构造器与参数匹配度越低...
//计算出当前构造器参数类型 与 当前 构造器参数 匹配度。
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
//条件成立:说明当前循环处理的 构造器 比上一次筛选出来的构造器 更优先。
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
判断bd是严格模式还是宽松模式,bd默认就是宽松模式,只有在ConfigurationClassBeanDefinition中使用严格模式,也就是扫描@Bean标注的方法注册的bd(对应的代码可以参考:ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod方法)
宽松模式:
public int getTypeDifferenceWeight(Class>[] paramTypes) {
// 计算实际使用的参数跟方法声明的参数的差异值
int typeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.arguments);
// 计算没有经过类型转换的参数跟方法声明的参数的差异值
int rawTypeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.rawArguments) - 1024;
return (rawTypeDiffWeight < typeDiffWeight ? rawTypeDiffWeight : typeDiffWeight);
}
public static int getTypeDifferenceWeight(Class>[] paramTypes, Object[] args) {
int result = 0;
for (int i = 0; i < paramTypes.length; i++) {
// 在出现类型转换时,下面这个判断才会成立,也就是在比较rawArguments跟paramTypes的差异时才可能满足这个条件
if (!ClassUtils.isAssignableValue(paramTypes[i], args[i])) {
return Integer.MAX_VALUE;
}
if (args[i] != null) {
Class> paramType = paramTypes[i];
Class> superClass = args[i].getClass().getSuperclass();
while (superClass != null) {
// 如果我们传入的值是方法上声明的参数的子类,那么每多一层继承关系,差异值加2
if (paramType.equals(superClass)) {
result = result + 2;
superClass = null;
}
else if (ClassUtils.isAssignable(paramType, superClass)) {
result = result + 2;
superClass = superClass.getSuperclass();
}
else {
superClass = null;
}
}
// 判断方法的参数是不是一个接口,如果是,那么差异值加1
if (paramType.isInterface()) {
result = result + 1;
}
}
}
return result;
}
严格模式:
public int getAssignabilityWeight(Class>[] paramTypes) {
// 严格模式下,只有三种返回值
// 1.Integer.MAX_VALUE,经过类型转换后还是不符合要求,返回最大的类型差异
// 因为解析后的参数可能返回一个NullBean(创建对象的方法返回了null,Spring会将其包装成一个NullBean),不过一般不会出现这种情况,所以我们可以当这种情况不存在
for (int i = 0; i < paramTypes.length; i++) {
if (!ClassUtils.isAssignableValue(paramTypes[i], this.arguments[i])) {
return Integer.MAX_VALUE;
}
}
// 2.Integer.MAX_VALUE - 512,进行过了类型转换才符合要求
for (int i = 0; i < paramTypes.length; i++) {
if (!ClassUtils.isAssignableValue(paramTypes[i], this.rawArguments[i])) {
return Integer.MAX_VALUE - 512;
}
}
// 3.Integer.MAX_VALUE - 1024,没有经过类型转换就已经符合要求了,返回最小的类型差异
return Integer.MAX_VALUE - 1024;
}