首页 > 其他分享 >@Autowired,@Resource,@Value,@Lazy注入的核心逻辑原理

@Autowired,@Resource,@Value,@Lazy注入的核心逻辑原理

时间:2024-03-22 16:30:58浏览次数:19  
标签:Lazy beanName return Autowired Object descriptor Bean Resource null

class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory {

    @Override
    @Nullable
    public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) {
        // 设置变量名解析器
        descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
        // 如果依赖的类型为Optional
        if (Optional.class == descriptor.getDependencyType()) {
            return createOptionalDependency(descriptor, requestingBeanName) {
                // 封装成一个嵌套的依赖描述信息,它保存了依赖的所有信息
                DependencyDescriptor descriptorToUse = new NestedDependencyDescriptor(descriptor) {
                    // 可以为空
                    @Override
                    public boolean isRequired() {
                        return false;
                    }

                    @Override
                    public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
                        // 直接获取Bean
                        return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) : beanFactory.getBean(beanName));

                    }
                };
                // 真正解析依赖的对象信息
                Object result = doResolveDependency(descriptorToUse, beanName, null, null);
                // 如果结果不是Option,包装一层
                return (result instanceof Optional ? (Optional<?>) result : Optional.ofNullable(result));
            }
        }
        // 类型为ObjectFactory,ObjectProvider,都是通过getObject获取注入对象
        if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) {
            // 统统返回DependencyObjectProvider对象
            return new DependencyObjectProvider(descriptor, requestingBeanName) {
                @Override
                public Object getObject(final Object... args) throws BeansException {
                    // 如果getObject的值是Optional类型
                    if (this.optional) {
                        // 上面有解释
                        return createOptionalDependency(this.descriptor, this.beanName, args);
                    } else {
                        // 创建一个依赖关系描述,它保存了依赖的所有信息
                        DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
                            @Override
                            public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
                                // 获取Bean
                                return beanFactory.getBean(beanName, args);
                            }
                        };
                        // 真正解析依赖的对象信息
                        Object result = doResolveDependency(descriptorToUse, this.beanName, null, null);
                        // 如果没有指定的Bean需要抛出异常
                        if (result == null) {
                            throw new NoSuchBeanDefinitionException(this.descriptor.getResolvableType());
                        }
                        return result;
                    }
                }
            }
        }
        // 类型为javax.inject.Provider
        if (javaxInjectProviderClass == descriptor.getDependencyType()) {
            return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName) {
                // Jsr330Provider extends DependencyObjectProvider
                // 所以,和上面ObjectFactory,ObjectProvider逻辑一样
                return new Jsr330Provider(descriptor, beanName) {
                    public Object get() throws BeansException {
                        return getValue() {
                            // 如果getObject的值是Optional类型
                            if (this.optional) {
                                return createOptionalDependency(this.descriptor, this.beanName);
                            } else {
                                // 真正解析依赖的对象信息
                                return doResolveDependency(this.descriptor, this.beanName, null, null);
                            }
                        }
                    }
                }
            }
        } else {
            // 其他类型
            // 获取自动注入的解析器,默认为BeanFactory中,默认为SimpleAutowireCandidateResolver,内部啥也没有
            // 在AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(), source);方法中
            // 如果不是ContextAnnotationAutowireCandidateResolver,统统设置为ContextAnnotationAutowireCandidateResolver
            // 所以,最终使用的ContextAnnotationAutowireCandidateResolver解析器解析注解
            // if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            //	  beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            // }
            AutowireCandidateResolver resolver = getAutowireCandidateResolver()
            // 解析@Lazy注解
            Object result = resolver.getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName) {
                return (isLazy(descriptor) {
                    // 遍历字段上所有的注解
                    for (Annotation ann : descriptor.getAnnotations()) {
                        // 获取Lazy注解
                        Lazy lazy = AnnotationUtils.getAnnotation(ann, Lazy.class);
                        // 如果存在,表示懒加载
                        if (lazy != null && lazy.value()) {
                            return true;
                        }
                    }
                    // 如果字段上没有,获取Set方法中是否存在Lazy注解
                    MethodParameter methodParam = descriptor.getMethodParameter();
                    if (methodParam != null) {
                        Method method = methodParam.getMethod();
                        // 如果没有操作该属性的方法,或者方法返回void,都从方法中获取Lazy注解
                        if (method == null || void.class == method.getReturnType()) {
                            Lazy lazy = AnnotationUtils.getAnnotation(methodParam.getAnnotatedElement(), Lazy.class);
                            if (lazy != null && lazy.value()) {
                                return true;
                            }
                        }
                    }
                    return false;
                } ?
                // 为注入的字段注入一个代理对象
                buildLazyResolutionProxy(descriptor, beanName) {
                    final DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) getBeanFactory();
                    TargetSource ts = new TargetSource() {
                        // 目标类型
                        public Class<?> getTargetClass() {
                            return descriptor.getDependencyType();
                        }

                        // 获取目标对象
                        public Object getTarget() {
                            // 真正解析这个bean
                            Object target = beanFactory.doResolveDependency(descriptor, beanName, null, null);
                            // 如果没有解析到,根据目标类型返回对应的空值,但不返回null
                            if (target == null) {
                                Class<?> type = getTargetClass();
                                if (Map.class == type) {
                                    return Collections.emptyMap();
                                } else if (List.class == type) {
                                    return Collections.emptyList();
                                } else if (Set.class == type || Collection.class == type) {
                                    return Collections.emptySet();
                                }
                                throw new NoSuchBeanDefinitionException(descriptor.getResolvableType(), "Optional dependency not present for lazy injection point");
                            }
                            // 返回从容器中解析到的Bean
                            return target;
                        }
                    };
                    // 创建注入的目标类型的代理对象
                    ProxyFactory pf = new ProxyFactory();
                    pf.setTargetSource(ts);
                    Class<?> dependencyType = descriptor.getDependencyType();
                    if (dependencyType.isInterface()) {
                        pf.addInterface(dependencyType);
                    }
                    return pf.getProxy(beanFactory.getBeanClassLoader());
                } :null);
            }
            // 如果被@Lazy处理成生成代理对象,则result为@Lazy生成的代理对象
            if (result == null) {
                // 真正解析依赖的对象信息
                result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
            }
            return result;
        }
    }

    /**
     * 真正解析依赖
     */
    public Object doResolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) {
        // 保存当前正在注入的字段信息
        InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
        try {
            // 空实现,让子类提供一个需要注入的Bean的快照信息
            Object shortcut = descriptor.resolveShortcut(this);
            if (shortcut != null) {
                return shortcut;
            }
            // 获取注入的类型
            Class<?> type = descriptor.getDependencyType();
            // 使用Autowire解析器,获取一个默认给定的建议的值,如果要手动给这个值,就实现这个方法
            Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor) {
                // 找字段上@Value注解的值
                Object value = findValue(descriptor.getAnnotations()) {
                    // 获取或方法上的所有注解信息
                    if (annotationsToSearch.length > 0) {
                        // 获取@Value注解
                        // private Class<? extends Annotation> valueAnnotationType = Value.class;
                        AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);
                        // 如果存在,获取注解的value值
                        if (attr != null) {
                            return extractValue(attr) {
                                Object value = attr.get(AnnotationUtils.VALUE);
                            }
                        }
                    }
                    return null;
                }
                // 如果没有,获取方法上的
                if (value == null) {
                    // 和上面字段找@Value注解一样
                    MethodParameter methodParam = descriptor.getMethodParameter();
                    if (methodParam != null) {
                        // 使用方法上所有的注解去找
                        value = findValue(methodParam.getMethodAnnotations());
                    }
                }
                return value;
            }
            // 如果找到了@Value的值
            if (value != null) {
                // 判断是否是String
                if (value instanceof String) {
                    // 如果是String,使用占位符解析器先处理占位符,解析到实际的值
                    String strVal = resolveEmbeddedValue((String) value);
                    // 先获取注入对象的BD
                    BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
                    // 计算SPEL表达式的值,这个是专门处理String类型的注入
                    value = evaluateBeanDefinitionString(strVal, bd);
                }
                // 获取类型转换器,转换解析到的最终字符串的实际值
                TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
                // 进行类型转换,从String->其他类型
                // 这里给个有趣的提示,就是默认情况下,例如@Value("b")想注入beanName为b的Bean,用@Value是无法注入Bean的
                // 但是通过特殊的类型转换器可以,一般也不会这么用,案例如下
                /**
                 * 注入一个类型转换器,通过String->转换为List,为什么不写成转换成Object呢?
                 * 因为源代码有逻辑,只会找精确的A->B类型的转换器,如果写成Object,那么注入的使用只能注入Object类注入
                 * 这样就没有任何意义了
                 * 例如   @Value("b)
                 *       private Object b;
                 * 再例如,这样就可以,它就会通过String->List找到我们的转换器,调用我们的转换方法,然后就可以成功注入
                 *       @Value("b")
                 *       List<B> b;
                 * @Primary
                 * @Bean
                 * public ConversionService conversionService(ApplicationContext context) {
                 *     ApplicationConversionService conversionService = new ApplicationConversionService();
                 *     conversionService.addConverter(String.class, List.class, new Converter<String, List>() {
                 *         @Override
                 *         public List convert(String source) {
                 *             Object bean = context.getBean(source);
                 *             return Arrays.asList(bean);
                 *         }
                 *     });
                 *     return conversionService;
                 * }
                 */
                return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
            }
            // 如果不存在@Value注解
            // 开始解析多个Bean,根据不同的类型解析,处理数组,Map,List,Collection,Stream
            Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter) {
                // 获取所有合格的Bean
                Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor) {
                    // 找到该类型的所有BeanName
                    String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                    for (String candidate : candidateNames) {
                        // 可以安全的赋值并且该Bean可以被注入
                        if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
                            // 添加注入的条目
                            addCandidateEntry(result, candidate, descriptor, requiredType) {
                                // 就是从Spring中找
                                Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this) {
                                    return beanFactory.getBean(beanName);
                                }
                            }
                        }
                    }
                }
            }
            // 如果找到了,直接返回
            if (multipleBeans != null) {
                return multipleBeans;
            }
            // 再找一次,这次找的Bean注入的类型是单个值,因为多个值的在上面已经处理好了
            Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
            // 如果没有找到
            if (matchingBeans.isEmpty()) {
                // 如果字段是必须的
                if (isRequired(descriptor)) {
                    // 抛出异常
                    raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
                }
                return null;
            }
            // 其他情况,注入单个Bean
            // 需要注入的beanName
            String autowiredBeanName;
            // 注入的实例
            Object instanceCandidate;
            // 如果存在多个可以注入的Bean
            if (matchingBeans.size() > 1) {
                // 确定最终注入的bean的BeanName
                autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor) {
                    // 获取依赖类型
                    Class<?> requiredType = descriptor.getDependencyType();
                    // 确定要注入的具体某一个Bean
                    String primaryCandidate = determinePrimaryCandidate(candidates, requiredType) {
                        String primaryBeanName = null;
                        for (Map.Entry<String, Object> entry : candidates.entrySet()) {
                            // 获取BD中设置主要的标识,或者@Primary,最终到会保存到BD中
                            boolean primary = getMergedLocalBeanDefinition(transformedBeanName).isPrimary();
                            if (primary) {
                                boolean candidateLocal = containsBeanDefinition(candidateBeanName);
                                boolean primaryLocal = containsBeanDefinition(primaryBeanName);
                                if (primaryBeanName != null) {
                                    // 如果上一次已经找到了,这次又找到了,表示存在多个,抛出异常
                                    if (candidateLocal && primaryLocal) {
                                        throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "more than one 'primary' bean found among candidates: " + candidates.keySet());
                                    } else if (candidateLocal) {
                                        // 保存主要的Bean的名称
                                        primaryBeanName = candidateBeanName;
                                    }
                                } else {
                                    // 保存主要的Bean的名称
                                    primaryBeanName = candidateBeanName;
                                }
                            }
                        }
                    }
                    // 如果有注入的对象
                    if (primaryCandidate != null) {
                        return primaryCandidate;
                    }
                    // 如果没有Primary标识,根据实现Order接口的顺序进行排序,必须排除顺序,有两个相同的顺序都会报错,和上面一样
                    String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
                    if (priorityCandidate != null) {
                        return priorityCandidate;
                    }
                    // 最后,找手动调用了registerResolvableDependency方法中resolvableDependencies存入的bean
                    // 如果有,就将手动注册的要解析的依赖返回
                    // beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
                    for (Map.Entry<String, Object> entry : candidates.entrySet()) {
                        String candidateName = entry.getKey();
                        Object beanInstance = entry.getValue();
                        if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) || matchesBeanName(candidateName, descriptor.getDependencyName())) {
                            return candidateName;
                        }
                    }
                    return null;
                }
                // 如果都没找到注入的BeanName
                if (autowiredBeanName == null) {
                    // 如果是必须得,或者是单个Bean的情况
                    if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
                        // 默认抛出异常,给子类实现
                        return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
                    } else {
                        // 如果是非必须得,或者是集合,多个的Bean,返回null
                        return null;
                    }
                }
                // 获取注入的实例Bean
                instanceCandidate = matchingBeans.get(autowiredBeanName);
            }
            // 如果只有一个Bean
            else {
                Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
                // 就直接保存key,value就行
                autowiredBeanName = entry.getKey();
                instanceCandidate = entry.getValue();
            }
            // 如果给定一个一个集合,让保存要注入的bean的情况
            if (autowiredBeanNames != null) {
                // 保存需要注入的BeanName
                autowiredBeanNames.add(autowiredBeanName);
            }
            // 如果注入的类型是Class
            if (instanceCandidate instanceof Class) {
                // 替换成bean对象
                instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this) {
                    return beanFactory.getBean(beanName);
                }
            }
            // 保存最终要注入的对象
            Object result = instanceCandidate;
            // 如果对象是一个空的Bean,表示容器中没有
            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);
        }
    }
}

标签:Lazy,beanName,return,Autowired,Object,descriptor,Bean,Resource,null
From: https://blog.csdn.net/JavaMyDream/article/details/136876633

相关文章

  • @Autowired注解与@Resource注解
    1.包来源@Autowired注解是spring框架自带的。@Resource注解是JDK扩展包中,使用需要引入(jdk8-11不需要引入)。2.装配规则@Autowired注解默认是根据类型byType装配,如果想根据名称装配,需要配合@Qualifier注解一起使用。@Resource注解默认根据名称byName装配,未指定name时,使用属性名......
  • k8s资源限制之LimitRange和ResourceQuota
    在Kubernetes中,LimitRange和ResourceQuota都是用于资源管理的工具,但它们的目的、作用范围和使用方式有所不同。作用范围LimitRange是在Pod和容器级别上进行资源限制的工具,主要用于设定CPU和内存两种计算资源的可用范围,并且还可以支持在PersistentVolumeClaim资源级别设定存储空......
  • C#之Lazy<T>
    Lazy<T>主要用在单例模式,是一种延迟加载(LazyLoading)的机制,它允许您推迟对象的创建直到第一次访问该对象。这种方式在需要时才分配资源,能够提高性能和资源利用率。Lazy类提供了一个简单且线程安全的方法来实现延迟加载。以下是Lazy的一些主要特点和用法:延迟加载:Lazy允许您将对象......
  • 【Lazy ORM】 小工具 acw 本地客户端 你负责点击页面,他负责输出代码
    介绍wu-smart-acw-client简称acw-client,是一个基于LazyORM定制的客户端代码生成小工具LazyORM小工具acw本地客户端你负责点击页面,他负责输出代码安装<dependency><groupId>top.wu2020</groupId><artifactId>wu-smart-acw-cli......
  • 【Lazy ORM】 小工具 acw 本地客户端 你负责点击页面,他负责输出代码
    介绍wu-smart-acw-client简称acw-client,是一个基于LazyORM定制的客户端代码生成小工具LazyORM小工具acw本地客户端你负责点击页面,他负责输出代码安装<dependency><groupId>top.wu2020</groupId><artifactId>wu-smart-acw-cli......
  • Vue:表单修饰符(.lazy/.number/.trim)
    一、v-model.lazy默认情况下,v-model 会在每次 input 事件后更新数据。也就是说在每次输入时都会改变绑定的值。例如,在下面的代码中,每次在输入框中输入时,number都会立即改变{{number}}<inputtype="text"v-model="number"/>有时候我们希望在一次输入结束后再......
  • 关于failed to load resource 问题的处理
    问题:c++做插件,写了一个nativeclass,继承于ue的类ActorComponent,而蓝图里也继承了这个c++class,都在插件里,每次打开的时候就有这个错误:之前的解决办法,复制文件到桌面上,然后删除本地这个文件,涉及到这个类的在做做改动,工作量挺大的,之前基于这个插件做了不少逻辑,所以要改动很久。......
  • 深入探索Spring注入:解锁@Autowired与构造器注入的秘密
    好久没有写JAVA了今天突然看到Sonarlint的提示  什么??竟然不推荐这样写?难道我一直写的都是错的??所以我深入了解了一下为什么要我改成构造函数注入在Spring框架中,依赖注入(DI)是一种核心功能,它允许对象通过构造函数、setter方法或字段直接定义其依赖关系。这里,我们专注于两种......
  • Spring中使用自带@Autowired注解实现策略模式
    场景SpringBoot中策略模式+工厂模式业务实例(接口传参-枚举类查询策略映射关系-执行不同策略)规避大量if-else:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/130503707设计模式-策略模式在Java中的使用示例:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/d......
  • 使用@Autowired + Map 实现策略模式
    创建接口publicinterfaceUserService{StringgetName();}创建多个类实现上面的接口实现一importcom.boot.service.UserService;importorg.springframework.stereotype.Service;@Service("zhangsan")publicclassZhangsanUserServiceImplimplementsUserServ......