Spring 系列目录(http://www.javashuo.com/article/p-kqecupyl-bm.html)html
Spring BeanFactory 的实现有三个重要的类,功能以下:java
AbstractBeanFactory
实现了 BeanFactory、 HierarchicalBeanFactory、ConfigurableBeanFactory 三个接口,最重要的方法是实现了 getBean(beanName) 接口,这个方法的最重要的步骤-建立 bean 则委托给模板方法 createBean 完成。git
AbstractAutowireCapableBeanFactory
实现了 AutowireCapableBeanFactory 接口,也就是依赖注入。同时实现了 crcreateBean(beanName, mbd, args) 建立 bean 的三个重要过程:实例化(createBeanInstance)、依赖注入(populateBean)、初始化(initializeBean)。其中依赖注入又分为 autowireByName 和 autowireByType 二种,其中名称查找很简单,而类型查找就复杂了不少。Spring 将类型查找委托给了子类的 resolveDependency 完成。github
DefaultListableBeanFactory
实现了 ConfigurableListableBeanFactory、BeanDefinitionRegistry 两个接口,提供了 Bean 和 BeanDefinition 查找注册的功能。 这个类一个很重要的功能是实现了模板方法 resolveDependency,这样就能够根据类型查找依赖。spring
在 populateBean(beanName, mbd, bw) 中能够看到有两种 bean 的查找方法:名称查找和类型查找,下面咱们来分析一下这两种查找方式。缓存
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } }
毫无疑问,直接从 BeanFactory 中取出这个 bean 就能够了。app
protected void autowireByName( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { if (containsBean(propertyName)) { Object bean = getBean(propertyName); pvs.add(propertyName, bean); registerDependentBean(propertyName, beanName); } } }
autowireByType 相比 autowireByName 就复杂多了,不过 autowireByType 直接委托给 resolveDependency 方法了,ide
protected void autowireByType( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<>(4); String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); if (Object.class != pd.getPropertyType()) { MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // 类型查找时容许对 FactoryBean 提早实例化对象,大部分状况一都是 true。 // 至于为何实现了 PriorityOrdered 接口的 bean 要排除,之后再研究一下??? boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance()); DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); // 核心代码就这一句,类型查找委托给了子类的 resolveDependency 完成 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { registerDependentBean(autowiredBeanName, beanName); } autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(ex); } } }
resolveDependency(desc, beanName, autowiredBeanNames, converter)
能够说是 AbstractAutowireCapableBeanFactory 最重要的模板方法了,子类 DefaultListableBeanFactory 进行了实现,做用就是根据类型查找依赖。ui
先解释一下 resolveDependency 这个方法的四个参数:this
descriptor
DependencyDescriptor 这个类实现了对字段、方法参数、构造器参数的进行依赖注入时的统一访问方式,你能够简单的认为是对这三种类型的封装。requestingBeanName
外层的 beanNameautowiredBeanNames
根据类型查找可能有多个,autowiredBeanNames 就是指查找到的 beanName 集合,Spring 支持 Array、Map、Collection 的注入。typeConverter
类型转换器,BeanWrapper 本身就是一个转换器。@Override public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); if (result == null) { result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; }
resolveDependency 方法将最重要的实现委托给了 doResolveDependency 完成。这里有两个类须要简单的说明一下:ParameterNameDiscovery 和 AutowireCandidateResolver。
ParameterNameDiscovery
这个类用于查找方法的参数的名称,默认的实现有 StandardReflectionParameterNameDiscoverer。详见:<>AutowireCandidateResolver
策略接口,对特定的依赖,这个接口决定一个特定的 BeanDefinition 是否知足做为自动绑定的备选项。在分析 doResolveDependency 方法以前,先看一下 findAutowireCandidates,这个方法是根据类型在容器中查找到全部可用的 bean。
protected Map<String, Object> findAutowireCandidates( @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { // 1. 根据类型查找父子容器中全部可用的 beanName,调用 getBeanNamesForType 方法。 // 注意 getBeanNamesForType 方法会过滤别名的状况 String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); // 2. 先查找缓存中 requiredType 的依赖,ok Map<String, Object> result = new LinkedHashMap<>(candidateNames.length); for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) { Class<?> autowiringType = classObjectEntry.getKey(); if (autowiringType.isAssignableFrom(requiredType)) { Object autowiringValue = classObjectEntry.getValue(); // 可能为一个 ObjectFactory 对象,调用 getObject 获取真实的对象 autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); if (requiredType.isInstance(autowiringValue)) { result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break; } } } // 3. 若是是非循环引用而且是合法的,ok for (String candidate : candidateNames) { // 所谓的循环引用是指 candidateName 实例的工厂就是 beanName 或就是自己 if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } // 4. 若是没有找到,有两种解决方案:一是回退操做,如 @Autowire 回退到名称查找,二是非集合类型考虑循环引用 if (result.isEmpty()) { // 判断要注入的类型是 Array、Map、Collection boolean multiple = indicatesMultipleBeans(requiredType); // 4.1 先执行回退操做 DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); for (String candidate : candidateNames) { if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) && (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) { addCandidateEntry(result, candidate, descriptor, requiredType); } } // 4.2 再考虑循环引用,但在集合类型中不容许循环引用本身 if (result.isEmpty() && !multiple) { for (String candidate : candidateNames) { if (isSelfReference(beanName, candidate) && (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) && isAutowireCandidate(candidate, fallbackDescriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } } } return result; }
findAutowireCandidates 都是真正中 BeanFactory 容器中根据类型查找,主要有如下几个步骤:
(1) 循环引用
// candidateName 实例的工厂就是 beanName 或就是自己 private boolean isSelfReference(@Nullable String beanName, @Nullable String candidateName) { return (beanName != null && candidateName != null && (beanName.equals(candidateName) || (containsBeanDefinition(candidateName) && beanName.equals(getMergedLocalBeanDefinition(candidateName).getFactoryBeanName())))); }
举个例子:
// <bean id="company" autowire="byType" class="com.github.binarylei.Company"/> @Test public void test() { DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(lbf); reader.loadBeanDefinitions(new ClassPathResource("spring-context-di-2.xml", getClass())); Company company = (Company) lbf.getBean("company"); } public static class Company { private Company company; private List<Company> companies; // 省略 setter }
上面的例子中 company 字段虽然有循环依赖的问题,依然能够正常注入,但其集合类型 companies 没法注入。
(2) 是否可用 isAutowireCandidate
DependencyDescriptor 对字段、方法参数、构造器参数进行统一的封装,配合 AutowireCandidateResolver 类一块儿解决依赖查找的问题。
@Override public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException { return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver()); } protected boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver) throws NoSuchBeanDefinitionException { String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName); if (containsBeanDefinition(beanDefinitionName)) { return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor, resolver); } else if (containsSingleton(beanName)) { return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver); } BeanFactory parent = getParentBeanFactory(); if (parent instanceof DefaultListableBeanFactory) { return ((DefaultListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor, resolver); } else if (parent instanceof ConfigurableListableBeanFactory) { return ((ConfigurableListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor); } else { return true; } } protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd, DependencyDescriptor descriptor, AutowireCandidateResolver resolver) { // 若是只有惟一的工厂方法,先解析出来。之后再来研究干什么用的??? String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName); resolveBeanClass(mbd, beanDefinitionName); if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) { new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd); } // 调用 AutowireCandidateResolver#isAutowireCandidate 方法判断是否可用 return resolver.isAutowireCandidate( new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor); }
isAutowireCandidate 最终调用了 AutowireCandidateResolver#isAutowireCandidate 方法,以 SimpleAutowireCandidateResolver 为例:
@Override public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) { return bdHolder.getBeanDefinition().isAutowireCandidate(); }
Spring 默认判断 BeanDefinition#autowireCandidate 属性,通常默认为 true。
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { // 将当前正在解决的依赖存放到 ThreadLocal 中,做用之后再研究??? InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { // 1. resolveShortcut 和 getSuggestedValue 都是对依赖解析前的拦截,这也很符全 Spring 的作法 Object shortcut = descriptor.resolveShortcut(this); if (shortcut != null) { return shortcut; } Class<?> type = descriptor.getDependencyType(); Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } // 2. 匹配多个,sine @Spring 4.3。若是 type 是 Array、List、Map 走这里,固然也有能够匹配不到 Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } // 3. 正常流程,只匹配一个,先找到全部可用的 matchingBeans // 若是有多个,则比较优先级肯定一个 // 若是没有,则根据依赖是不是必需的抛出异常 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } String autowiredBeanName; Object instanceCandidate; // 3.1 匹配到多个,则根据优先级选一个。注意集合类型容许为空 if (matchingBeans.size() > 1) { // 3.1.1 根据 Primary 属性或 PriorityOrdered 接口指定优先级 autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null) { // 3.1.2 若是是必需的或非集合类型,那么就根据 DependencyDescriptor 指定的规则选择一个最优的 if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans); // 3.1.3 集合类型容许为 null } else { return null; } } instanceCandidate = matchingBeans.get(autowiredBeanName); // 3.2 精确匹配一个 } else { Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null) { autowiredBeanNames.add(autowiredBeanName); } if (instanceCandidate instanceof Class) { instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); } // 4. 校验 Object result = instanceCandidate; if (result instanceof NullBean) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } result = null; } if (!ClassUtils.isAssignableValue(type, result)) { throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass()); } return result; } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } }
doResolveDependency 这个方法有点长,大概能够分为三步:
findAutowireCandidates 方法咱们前面已经看过了,根据类型查找全部的依赖。其实 resolveMultipleBeans 也是调用这个方法。咱们只看一下 List 集合是怎么处理的:
if (Collection.class.isAssignableFrom(type) && type.isInterface()) { // 1. 解析泛型的真实类型 eg List<User> 是 User Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric(); if (elementType == null) { return null; } // 2. 调用 findAutowireCandidates 查找全部的类型 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } // 3. 类型转换 TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), type); // 4. 排序 if (result instanceof List) { Comparator<Object> comparator = adaptDependencyComparator(matchingBeans); if (comparator != null) { ((List<?>) result).sort(comparator); } } return result; }
至此,根据类型查找依赖已经完成。
参考:
1 . 《Spring各类依赖注入注解的区别》:https://blog.csdn.net/gaohe7091/article/details/39319363
天天用心记录一点点。内容也许不重要,但习惯很重要!