1 Star 0 Fork 156

南风不竞 / Spring-Analysis

forked from huifer / Code-Analysis 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
Spring-ContextAnnotationAutowireCandidateResolver-未完成.md 5.43 KB
一键复制 编辑 原始数据 按行查看 历史
huifer 提交于 2020-12-08 09:19 . feat: 0.0.10

Spring ContextAnnotationAutowireCandidateResolver

  • 类全路径: org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver

  • 类图

    AutowireCandidateResolver.png

方法分析

从接口实现上仅有一个getLazyResolutionProxyIfNecessary方法, 其他的都在父类上. 详细请查看下面文章。

下面对 getLazyResolutionProxyIfNecessary 进行分析

getLazyResolutionProxyIfNecessary

  • 方法签名: org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver#getLazyResolutionProxyIfNecessary
  • 方法作用: 获取懒加载的对象(代理对象)
getLazyResolutionProxyIfNecessary 详细代码如下
@Override
@Nullable
public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {
   // 判断是否懒加载
   return (isLazy(descriptor) ? buildLazyResolutionProxy(descriptor, beanName) : null);
}

在阅读代码后我们有两个方法. 不是很了解. 再根据方法的作用我们大概推断出

  1. isLazy 判断是否懒加载
  2. buildLazyResolutionProxy 构建代理对象

下面对两个方法进行分析

isLazy

  • 方法签名: org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver#isLazy

整段代码分为上下两段 我们先看第一段

isLazy 第一段 详细代码如下
// 第一部分
// 获取注解循环
for (Annotation ann : descriptor.getAnnotations()) {
   // 得到 lazy 注解
   Lazy lazy = AnnotationUtils.getAnnotation(ann, Lazy.class);
   // 判断 lazy 的注解值是否 true
   if (lazy != null && lazy.value()) {
      return true;
   }
}

第一段的行为是从依赖描述中找到所有的注解,在这些注解中找到Lazy注解, 通过Lazy注解的数据来确定是否是懒加载的

下面阅读第二段代码

isLazy 第二段 详细代码如下
// 第二部分
// 获取方法参数对象
MethodParameter methodParam = descriptor.getMethodParameter();
if (methodParam != null) {
   // 获取 method
   Method method = methodParam.getMethod();
   if (method == null || void.class == method.getReturnType()) {
      // method 上寻找 lazy 注解
      Lazy lazy = AnnotationUtils.getAnnotation(methodParam.getAnnotatedElement(), Lazy.class);
      return lazy != null && lazy.value();
   }
}
return false;

第二段主要操作对象是**MethodParameter, 从MethodParameter 提取 Method 在Method上寻找 Lazy 注解, 最后和第一段一样通过Lazy**注解的数据来确定是否懒加载

buildLazyResolutionProxy

  • 方法签名: org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver#buildLazyResolutionProxy

  • 方法作用: 创建懒加载对象的代理类

buildLazyResolutionProxy 详细代码如下
/**
 * 创建延迟代理类
 */
protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final @Nullable String beanName) {
   Assert.state(getBeanFactory() instanceof DefaultListableBeanFactory,
         "BeanFactory needs to be a DefaultListableBeanFactory");
   final DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) getBeanFactory();
   // target source 接口 目标对象
   TargetSource ts = new TargetSource() {
      @Override
      public Class<?> getTargetClass() {
         return descriptor.getDependencyType();
      }

      @Override
      public boolean isStatic() {
         return false;
      }

      @Override
      public Object getTarget() {
         // DefaultListableBeanFactory 中 doResolveDependency 调用
         Object target = beanFactory.doResolveDependency(descriptor, beanName, 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");
         }
         return target;
      }

      @Override
      public void releaseTarget(Object target) {
      }
   };
   // 代理工厂
   ProxyFactory pf = new ProxyFactory();
   // 设置数据信息
   pf.setTargetSource(ts);
   Class<?> dependencyType = descriptor.getDependencyType();
   if (dependencyType.isInterface()) {
      pf.addInterface(dependencyType);
   }
   // 代理工厂创建对象
   return pf.getProxy(beanFactory.getBeanClassLoader());
}

对于这段代码需要了解AOP相关的内容, 在目前阶段还没有开展AOP相关内容的分析这段代码暂时停留.

下面标出几个有关类

  1. DefaultListableBeanFactory: 分析文章
  2. TargetSource: 分析文章
  3. ProxyFactory: 分析文章
Java
1
https://gitee.com/limengcanyu/spring-analysis.git
git@gitee.com:limengcanyu/spring-analysis.git
limengcanyu
spring-analysis
Spring-Analysis
master

搜索帮助