Spring 5 DefaultListableBeanFactory-- isAutowireCandidate源码分析

相关源码注释

ApplicationContext

Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释

BeanFactory

Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释

isAutowireCandidate(String , DependencyDescriptor )

确定指定的bean定义是否可以自动注入:

  1. 获取此BeanFactory的自动装配候选解析器
  2. 交由isAutowireCandidate(String, DependencyDescriptor, AutowireCandidateResolver) 处理并将结果返回出去
/**
	 * 确定指定的bean定义是否可以自动注入
	 * @param beanName the name of the bean to check -- 要检查的bean名
	 * @param descriptor the descriptor of the dependency to resolve -- 要解决的依赖项的描述符
	 * @return 是否应将bean视为自动装配候选对象
	 * @throws NoSuchBeanDefinitionException 如果没有给定名称的bean
	 */
	@Override
	public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
			throws NoSuchBeanDefinitionException {
    
    
		return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver());
	}

isAutowireCandidate(String, DependencyDescriptor, AutowireCandidateResolver)

确定指定的bean定义是否可以自动注入:

  1. 解决beanName存在于该工厂的情况:
    1. 去除开头的’&'字符,返回剩余的字符串作为转换后的Bean名称【全类名】【变量 beanDefinitionName】
    2. 如果工厂包含beanDefinitionName得BeanDefinition对象,就确定beanDefinitionName的合并后RootBeanDefinition 是否符合自动装配候选条件,以注入到声明匹配类型依赖项的其他bean中并将结果返回出去
    3. 如果beanName在该BeanFactory的单例对象的高速缓存Map集合【DefaultSingletonBeanRegistry.singletonObjects】中, 获取beanName的Class对象,从而构建出RootBeanDefinition实例对象,最后确定该RootBeanDefinition实例对象是否符合自动装 配候选条件,以注入到声明匹配类型依赖项的其他bean中并将结果返回出去
  2. 解决beanName存在于该工厂的父工厂的情况:
    1. 获取父工厂【变量 parent】
    2. 如果父工厂是DefaultListableBeanFactory的实例对象,递归交由父工厂的该方法处理并将结果返回
    3. 如果父工厂是ConfigurableListableBeanFactory的实例对象,就递归交由父工厂的isAutowireCandidate(String, DependencyDescriptor) 进行处理并将结果返回出去
  3. 如果上面各种情况都没有涉及,默认是返回true,表示应将bean视为自动装配候选对象
/**
	 * <p>确定指定的bean定义是否可以自动注入 </p>
	 * Determine whether the specified bean definition qualifies as an autowire candidate,
	 * to be injected into other beans which declare a dependency of matching type.
	 * <p>确定指定的bean定义是否符合自动装配候选条件,以注入到声明匹配类型依赖项的其他bean中。</p>
	 * @param beanName the name of the bean definition to check
	 *                 -- 要检查的beanDefinition名称
	 * @param descriptor the descriptor of the dependency to resolve
	 *                   -- 要解析的依赖项的描述符
	 * @param resolver the AutowireCandidateResolver to use for the actual resolution algorithm
	 *                 -- AutowireCandidateResolver用于实际的解析算法
	 * @return whether the bean should be considered as autowire candidate
	 *  -- 是否应将bean视为自动装配候选对象
	 * @see #isAutowireCandidate(String, RootBeanDefinition, DependencyDescriptor, AutowireCandidateResolver)
	 */
	protected boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
			throws NoSuchBeanDefinitionException {
    
    
		//去除开头的'&'字符,返回剩余的字符串作为转换后的Bean名称【全类名】
		String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
		//如果工厂包含beanDefinitionName得BeanDefinition对象
		if (containsBeanDefinition(beanDefinitionName)) {
    
    
			//确定beanDefinitionName的合并后RootBeanDefinition是否符合自动装配候选条件,以注入到声明匹配类型依赖项的其他bean中
			// 并将结果返回出去
			return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor, resolver);
		}
		//这里应该是直接调用registerSingeton(String,Object)方法的情况
		//如果beanName在该BeanFactory的singletonObjects【单例对象的高速缓存Map集合】中
		else if (containsSingleton(beanName)) {
    
    
			//获取beanName的Class对象,从而构建出RootBeanDefinition实例对象,最后确定该RootBeanDefinition实例对象是否符合自动装
			// 配候选条件,以注入到声明匹配类型依赖项的其他bean中并将结果返回出去
			return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver);
		}
		//获取父工厂
		BeanFactory parent = getParentBeanFactory();
		//如果父工厂是DefaultListableBeanFactory的实例对象
		if (parent instanceof DefaultListableBeanFactory) {
    
    
			// No bean definition found in this factory -> delegate to parent.
			// 在该工厂中找不到BeanDefinition ->委托给父对象
			// 递归交由父工厂处理并将结果返回
			return ((DefaultListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor, resolver);
		}
		//如果父工厂是ConfigurableListableBeanFactory的实例对象
		else if (parent instanceof ConfigurableListableBeanFactory) {
    
    
			// If no DefaultListableBeanFactory, can't pass the resolver along.
			// 如果没有DefaultLisableBeanFactory,则无法传递解析器
			// 这个时候,由于ConfigurableListableBeanFactory没有提供isAutowireCandidate(String, DependencyDescriptor, AutowireCandidateResolver)的
			// 重载方法,所以递归交由父工厂的isAutowireCandidate(String, DependencyDescriptor)进行处理并将结果返回出去
			return ((ConfigurableListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor);
		}
		else {
    
    
			//如果上面各种情况都没有涉及,默认是返回true,表示应将bean视为自动装配候选对象
			return true;
		}
	}

isAutowireCandidate(String, RootBeanDefinition, DependencyDescriptor, AutowireCandidateResolver)

确定mbd可以自动注入到descriptor所包装的field/methodParam中:

  1. 去除开头的’&'字符,返回剩余的字符串作为转换后的Bean名称【可能是全类名】【变量 beanDefinitionName】
  2. 为mdb解析出对应的bean class对象
  3. 如果mbd指明了引用非重载方法的工厂方法名称【RootBeanDefinition.isFactoryMethodUnique】 且 mbd还没有缓存 用于自省的唯一工厂方法候选【RootBeanDefinition.factoryMethodToIntrospect】:如果可能,新建一个ConstuctorResolver 对象来解析mbd中factory方法
  4. 根据mbd,beanName,beanDefinitionName的别名构建一个BeanDefinitionHolder实例,交给resolver进行判断, 是否可以自动注入并将结果返回出去。resolver的判断依据还是看mdb的AbstractBeanDefinition.isAutowireCandidate()结果。
/**
	 * <p>
	 *  确定mbd可以自动注入到descriptor所包装的field/methodParam中
	 * </p>
	 * Determine whether the specified bean definition qualifies as an autowire candidate,
	 * to be injected into other beans which declare a dependency of matching type.
	 * <p>确定指定的bean定义是否符合自动装配候选条件,以注入到声明匹配类型依赖项的其他bean中。</p>
	 * @param beanName the name of the bean definition to check -- 要检查的beanDefinition名
	 * @param mbd the merged bean definition to check -- 要检查的合并后BeanDefinition
	 * @param descriptor the descriptor of the dependency to resolve -- 要解析的依赖项的描述符
	 * @param resolver the AutowireCandidateResolver to use for the actual resolution algorithm
	 *                 -- AutowireCandidateResolver用于实际的分析算法
	 * @return whether the bean should be considered as autowire candidate
	 *  -- 是否应将bean视为自动装配候选对象
	 */
	protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
			DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {
    
    
		//去除开头的'&'字符,返回剩余的字符串作为转换后的Bean名称【可能是全类名】
		String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
		//为mdb解析出对应的bean class对象
		resolveBeanClass(mbd, beanDefinitionName);
		//如果mbd指明了引用非重载方法的工厂方法名称 且 mbd还没有缓存用于自省的唯一工厂方法候选
		if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
    
    
			//如果可能,新建一个ConstuctorResolver对象来解析mbd中factory方法
			new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
		}
		//根据mbd,beanName,beanDefinitionName的别名构建一个BeanDefinitionHolder实例,交给resolver进行判断
		// 是否可以自动注入。resolver的判断依据还是看mdb的isAutowireCandidate()结果。
		return resolver.isAutowireCandidate(
				new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor);
	}

BeanFactoryUtils.transformedBeanName(beanName);

去除开头的’&'字符,返回剩余的字符串作为转换后的Bean名称【可能是全类名】:

  1. 如果name为null,抛出异常
  2. 如果name不是以’&'开头,就直接返回
  3. 从具有FactoryBean前缀的名称缓存到剥离的名称的ConcurrentHashMap【transformedBenaNameCache】 中获取bean名对应的转换后的名称并返回
  4. 获取不到时就构建一个:从name的开头位置去掉’&’,再重新检查是否还是以’&‘开头,是的话就再截直到没有出现’&'开头为止。所得到 的字符串就是Bean名称【可能是全类名】
/**
	 * Cache from name with factory bean prefix to stripped name without dereference.
	 * <p>从具有FactoryBean前缀的名称缓存到剥离的名称,而无需取消引用</p>
	 * @since 5.1
	 * @see BeanFactory#FACTORY_BEAN_PREFIX
	 */
	private static final Map<String, String> transformedBeanNameCache = new ConcurrentHashMap<>();
	
/**
	 * <p>去除开头的'&'字符,返回剩余的字符串作为转换后的Bean名称【可能是全类名】
	 * </p>
	 * Return the actual bean name, stripping out the factory dereference
	 * prefix (if any, also stripping repeated factory prefixes if found).
	 * <p>返回实际的bean名称,删除工厂取消引用前缀(如果有的话,还删除重复的
	 * 工厂前缀(如果找到))</p>
	 * <p>用于获取以'&'开头的name对应的bean名,如果bean不是'&'开头,就直接返回该name</p>
	 * @param name the name of the bean - bean名
	 * @return the transformed name - 转换后的名称
	 * @see BeanFactory#FACTORY_BEAN_PREFIX
	 */
	public static String transformedBeanName(String name) {
    
    
		//如果bean名为null,抛出异常
		Assert.notNull(name, "'name' must not be null");
		//如果bean名不是以'&'开头,就直接返回
		if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
    
    
			return name;
		}
		//从transformedBenaNameCache中获取bean名对应的转换后的名称
		return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
    
    
			//从beanName的开头位置去掉'&',并重新赋值给beanName,再重新检查是还是以'&'开头,是的话就再截
			// 知道开头不是以'&'开头后,加入到transformedBeanNameCache中
			do {
    
    
				beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
			}
			while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
			return beanName;
		});
	}

ConstructorResolver

Spring 5 ConstructorResolver源码注释

AutowireCandidateResolver

Spring 5 AutowireCandidateResolver源码注释

猜你喜欢

转载自blog.csdn.net/qq_30321211/article/details/108362842
今日推荐