DefaultListableBeanFactory介绍
BeanFactory是个Factory,也就是IOC容器或对象工厂,而DefaultListableBeanFactory是Bean工厂的一个默认实现,DefaultListableBeanFactory提供了原始的BeanFactory的功能,如:对外提供getBean()方法,维护一张beanDefinitionMap表
继承关系
DefaultListableBeanFactory继承关系如下,可以看出DefaultListableBeanFactory尚有子类XmlBeanFactory
接口实现
下图列出了DefaultListableBeanFactory的接口实现和继承图,DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,并且实现BeanFactory接口,提供了根本的BeanFactory功能。
BeanDefinitionRegistry是一个接口,它定义了关于BeanDefinition的注册、移除、查询等一系列的操作。
BeanFactory是IOC容器的核心接口,它的职责包罗:实例化、定位、配置应用步伐中的对象及创建这些对象间的依赖。
源码码解析
属性成员
beanDefinitionMap:DefaultListableBeanFactory作为BeanFactory默认是维护这一张beanDefinition的表。
- /** Map of bean definition objects, keyed by bean name. */
- private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
复制代码 getbean方法
DefaultListableBeanFactory是Bean工厂的一个默认实现,DefaultListableBeanFactory是Bean工厂的一个默认实现。截取DefaultListableBeanFactory中与getBean方法。
可以发现getBean有两种方式获取bean:
- 根据名称获取Bean,这个方法继承于AbstractBeanFactory
- 根据类型获取Bean,这个方法实现于DefaultListableBeanFactory,属于扩展了getBean方式
- //---------------------------------------------------------------------
- // Implementation of remaining BeanFactory methods
- //---------------------------------------------------------------------
- //这个方式属于是扩展了getBean的方式,通过类型获取Bean
- @Override
- public <T> T getBean(Class<T> requiredType) throws BeansException {
- return getBean(requiredType, (Object[]) null);
- }
- @SuppressWarnings("unchecked")
- @Override
- public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
- Assert.notNull(requiredType, "Required type must not be null");
- //根据类型解析bean
- Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);
- if (resolved == null) {
- throw new NoSuchBeanDefinitionException(requiredType);
- }
- return (T) resolved;
- }
复制代码 setAutowireCandidateResolver方法
这是一个普通的set方法,为什么我还要介绍它呢,由于这个set方法能启动扩展DefaultListableBeanFactory的功能。通过该方法给DefaultListableBeanFactory扩展主动装配的解析器。
可以通过该方法添加格外的主动装配解析器,如:QualifierAnnotationAutowireCandidateResolver提供@Qualifier注解解析的功能和@Autowire
- /**
- * Set a custom autowire candidate resolver for this BeanFactory to use
- * when deciding whether a bean definition should be considered as a
- * candidate for autowiring.
- */
- public void setAutowireCandidateResolver(AutowireCandidateResolver autowireCandidateResolver) {
- Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null");
- if (autowireCandidateResolver instanceof BeanFactoryAware) {
- if (System.getSecurityManager() != null) {
- AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
- ((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
- return null;
- }, getAccessControlContext());
- }
- else {
- ((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
- }
- }
- this.autowireCandidateResolver = autowireCandidateResolver;
- }
复制代码 resolveDependency方法
resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, TypeConverter typeConverter)方法,找到对应的依赖 Bean,获取 Bean 的实例对象时,构造器注入的参数也是通过该方法获取的,依赖注入底层也是通过该方法实现的,这里我们对该方法一探究竟
- // DefaultListableBeanFactory.java
- @Override
- @Nullable
- public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
- @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
- // <1> 设置参数名称探测器,例如通过它获取方法参数的名称
- descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
- // <2> 如果依赖类型为 Optional 类型
- if (Optional.class == descriptor.getDependencyType()) {
- // 调用 `createOptionalDependency(...)` 方法,先将 `descriptor` 注入表述器封装成 NestedDependencyDescriptor 对象
- // 底层处理和下面的 `5.2` 相同
- return createOptionalDependency(descriptor, requestingBeanName);
- }
- // <3> 否则,如果依赖类型为 ObjectFactory 或 ObjectProvider 类型
- else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) {
- // 返回一个 DependencyObjectProvider 私有内部类对象,并没有获取到实例的 Bean,需要调用其 getObject() 方法获取目标对象
- return new DependencyObjectProvider(descriptor, requestingBeanName);
- }
- // <4> 否则,如果依赖类型为 javax.inject.Provider 类型
- else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
- // 返回一个 Jsr330Provider 私有内部类对象,该对象也继承 DependencyObjectProvider
- return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
- }
- // <5> 否则,通用的处理逻辑
- else {
- // <5.1> 先通过 AutowireCandidateResolver 尝试获取一个代理对象,延迟依赖注入则会返回一个代理对象
- Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
- // <5.2> 如果上面没有返回代理对象,则进行处理,调用 `doResolveDependency(...)` 方法
- if (result == null) {
- result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
- }
- return result;
- }
- }
复制代码 doResolveDependency方法
- // DefaultListableBeanFactory.java
- @Nullable
- public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
- @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
- // 设置当前线程的注入点,并返回上次的注入点,属于嵌套注入的一个保护点
- InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
- try {
- // <1> 针对给定的工厂给定一个快捷实现的方式,暂时忽略
- // 例如考虑一些预先解析的信息,在进入所有 Bean 的常规类型匹配算法之前,解析算法将首先尝试通过此方法解析快捷方式
- Object shortcut = descriptor.resolveShortcut(this);
- if (shortcut != null) {
- // 返回快捷的解析信息
- return shortcut;
- }
- // 依赖的类型
- Class<?> type = descriptor.getDependencyType();
- // <2> 获取注解中的 value 对应的值,例如 @Value、@Qualifier 注解配置的 value 属性值,注意 @Autowired 没有 value 属性配置
- Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
- if (value != null) {
- if (value instanceof String) {
- // <2.1> 解析注解中的 value,因为可能是占位符,需要获取到相应的数据
- String strVal = resolveEmbeddedValue((String) value);
- BeanDefinition bd = (beanName != null && containsBean(beanName) ?
- getMergedBeanDefinition(beanName) : null);
- value = evaluateBeanDefinitionString(strVal, bd);
- }
- TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
- try {
- // <2.2> 进行类型转换,并返回
- return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
- }
- catch (UnsupportedOperationException ex) {
- // A custom TypeConverter which does not support TypeDescriptor resolution...
- return (descriptor.getField() != null ?
- converter.convertIfNecessary(value, type, descriptor.getField()) :
- converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
- }
- }
- // <3> 解析复合的依赖对象(Array、Collection、Map 类型),获取该属性元素类型的 Bean 们
- // 底层和第 `4` 原理一样,这里会将 `descriptor` 封装成 MultiElementDescriptor 类型
- Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
- if (multipleBeans != null) {
- return multipleBeans;
- }
- // <4> 查找与类型相匹配的 Bean 们
- // 返回结果:key -> beanName;value -> 对应的 Bean
- Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
- // <5> 如果一个都没找到
- if (matchingBeans.isEmpty()) {
- // <5.1> 如果 @Autowired 配置的 required 为 true,表示必须,则抛出异常
- if (isRequired(descriptor)) {
- raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
- }
- // <5.2> 否则,返回一个空对象
- return null;
- }
- String autowiredBeanName;
- Object instanceCandidate;
- // <6> 如果匹配的 Bean 有多个,则需要找出最优先的那个
- if (matchingBeans.size() > 1) {
- // <6.1> 找到最匹配的那个 Bean,通过 @Primary 或者 @Priority 来决定,或者通过名称决定
- autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
- if (autowiredBeanName == null) {
- if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
- // <6.2> 如果没有找到最匹配的 Bean,则抛出 NoUniqueBeanDefinitionException 异常
- return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
- }
- else {
- // In case of an optional Collection/Map, silently ignore a non-unique case:
- // possibly it was meant to be an empty collection of multiple regular beans
- // (before 4.3 in particular when we didn't even look for collection beans).
- return null;
- }
- }
- // <6.3> 获取到最匹配的 Bean,传值引用给 `instanceCandidate`
- instanceCandidate = matchingBeans.get(autowiredBeanName);
- }
- // <7> 否则,只有一个 Bean,则直接使用其作为最匹配的 Bean
- else {
- // We have exactly one match.
- Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
- autowiredBeanName = entry.getKey();
- instanceCandidate = entry.getValue();
- }
- // <8> 将依赖注入的 Bean 的名称添加至方法入参 `autowiredBeanNames` 集合,里面保存依赖注入的 beanName
- if (autowiredBeanNames != null) {
- autowiredBeanNames.add(autowiredBeanName);
- }
- // <9> 如果匹配的 Bean 是 Class 对象,则根据其 beanName 依赖查找到对应的 Bean
- if (instanceCandidate instanceof Class) {
- instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
- }
- 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());
- }
- // <10> 返回依赖注入的 Bean
- return result;
- }
- finally {
- // 设置当前线程的注入点为上一次的注入点,因为本次注入结束了
- ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
- }
- }
复制代码 findAutowireCandidates 方法
- // DefaultListableBeanFactory.java
- protected Map<String, Object> findAutowireCandidates(
- @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
- // <1> 从当前上下文找到该类型的 Bean 们(根据类型)
- String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
- this, requiredType, true, descriptor.isEager());
- // <2> 定义一个 Map 对象 `result`,用于保存符合条件的 Bean
- Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
- /**
- * <3> 遍历 Spring 内部已处理的依赖对象集合,可以跳到 AbstractApplicationContext#prepareBeanFactory 方法中看看
- * 会有一下几个内置处理对象:
- * BeanFactory 类型 -> 返回 DefaultListableBeanFactory
- * ResourceLoader、ApplicationEventPublisher、ApplicationContext 类型 -> 返回 ApplicationContext 对象
- */
- for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
- Class<?> autowiringType = classObjectEntry.getKey();
- if (autowiringType.isAssignableFrom(requiredType)) {
- Object autowiringValue = classObjectEntry.getValue();
- autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
- if (requiredType.isInstance(autowiringValue)) {
- result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
- break;
- }
- }
- }
- // <4> 遍历第 `1` 步找到的 Bean 的名称们
- for (String candidate : candidateNames) {
- // <4.1> 如果满足下面两个条件,则添加至 `result` 集合中
- if (!isSelfReference(beanName, candidate) // 如果不是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)
- && isAutowireCandidate(candidate, descriptor)) { // 符合注入的条件
- addCandidateEntry(result, candidate, descriptor, requiredType);
- }
- }
- // <5> 如果没有找到符合条件的 Bean,则再尝试获取
- if (result.isEmpty()) {
- boolean multiple = indicatesMultipleBeans(requiredType);
- // Consider fallback matches if the first pass failed to find anything...
- DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
- // <5.1> 再次遍历第 `1` 步找到的 Bean 的名称们
- for (String candidate : candidateNames) {
- // <5.2> 如果满足下面三个条件,则添加至 `result` 集合中
- if (!isSelfReference(beanName, candidate) // 如果不是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)
- && isAutowireCandidate(candidate, fallbackDescriptor) // 符合注入的条件
- && (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) { // 不是复合类型,或者有 @Qualifier 注解
- addCandidateEntry(result, candidate, descriptor, requiredType);
- }
- }
- // <6> 如果还没有找到符合条件的 Bean,则再尝试获取
- // 和上面第 `5` 步的区别在于必须是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)
- if (result.isEmpty() && !multiple) {
- // Consider self references as a final pass...
- // but in the case of a dependency collection, not the very same bean itself.
- for (String candidate : candidateNames) {
- if (isSelfReference(beanName, candidate)
- && (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate))
- && isAutowireCandidate(candidate, fallbackDescriptor)) {
- addCandidateEntry(result, candidate, descriptor, requiredType);
- }
- }
- }
- }
- // <7> 返回 `result`,符合条件的 Bean
- return result;
- }
复制代码 determineAutowireCandidate 方法
determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor)方法,找到最匹配的那个依赖注入对象,如下:
- @Nullable
- protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
- Class<?> requiredType = descriptor.getDependencyType();
- // <1> 尝试获取一个 @Primary 注解标注的 Bean,如果有找到多个则会抛出异常
- String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
- // <2> 如果第 `1` 步找到了则直接返回
- if (primaryCandidate != null) {
- return primaryCandidate;
- }
- // <3> 尝试找到 @Priority 注解优先级最高的那个 Bean,如果存在相同的优先级则会抛出异常
- String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
- // <4> 如果第 `3` 步找到了则直接返回
- if (priorityCandidate != null) {
- return priorityCandidate;
- }
- // Fallback
- // <5> 兜底方法,遍历所有的 Bean
- for (Map.Entry<String, Object> entry : candidates.entrySet()) {
- String candidateName = entry.getKey();
- Object beanInstance = entry.getValue();
- // <5.1> 如果满足下面其中一个条件则直接返回
- if ((beanInstance != null
- && this.resolvableDependencies.containsValue(beanInstance)) // 该 Bean 为 Spring 内部可处理的 Bean,例如 ApplicationContext
- || matchesBeanName(candidateName, descriptor.getDependencyName())) { // 名称相匹配
- return candidateName;
- }
- }
- // <6> 上面都没选出来则返回一个空对象
- return null;
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |