spring源码解析@Value

前言

本次介绍下@Value这个注解的底层实现

正文

本次介绍下@Value的底层实现

底层是先解析这个里面配置的表达式解析,再进行依赖注入

表达式解析

进入

org.springframework.context.expression.StandardBeanExpressionResolver#evaluate

@Override
   @Nullable
   public Object evaluate(@Nullable String value, BeanExpressionContext evalContext) throws BeansException {
      if (!StringUtils.hasLength(value)) {
         return value;
      }
      try {
//       从缓存中取关于这个值的表达式对象
         Expression expr = this.expressionCache.get(value);
         if (expr == null) {
            expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext);
            this.expressionCache.put(value, expr);
         }
         StandardEvaluationContext sec = this.evaluationCache.get(evalContext);
         if (sec == null) {
            sec = new StandardEvaluationContext();
            sec.setRootObject(evalContext);
            sec.addPropertyAccessor(new BeanExpressionContextAccessor());
            sec.addPropertyAccessor(new BeanFactoryAccessor());
            sec.addPropertyAccessor(new MapAccessor());
            sec.addPropertyAccessor(new EnvironmentAccessor());
            sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory()));
            sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));
            ConversionService conversionService = evalContext.getBeanFactory().getConversionService();
            if (conversionService != null) {
               sec.setTypeConverter(new StandardTypeConverter(conversionService));
            }
            customizeEvaluationContext(sec);
            this.evaluationCache.put(evalContext, sec);
         }
         return expr.getValue(sec);
      }
      catch (Throwable ex) {
         throw new BeanExpressionException("Expression parsing failed", ex);
      }
   }
expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext);

进入

org.springframework.expression.common.TemplateAwareExpressionParser#parseExpression(java.lang.String, org.springframework.expression.ParserContext)

@Override
   public Expression parseExpression(String expressionString, @Nullable ParserContext context) throws ParseException {
      if (context != null && context.isTemplate()) {
         return parseTemplate(expressionString, context);
      }
      else {
//       表达式解析
         return doParseExpression(expressionString, context);
      }
   }

这一行

//        表达式解析
         return doParseExpression(expressionString, context);

进入

org.springframework.expression.spel.standard.SpelExpressionParser#doParseExpression

@Override
protected SpelExpression doParseExpression(String expressionString, @Nullable ParserContext context) throws ParseException {
   return new InternalSpelExpressionParser(this.configuration).doParseExpression(expressionString, context);
}

进入

org.springframework.expression.spel.standard.InternalSpelExpressionParser#doParseExpression

@Override
protected SpelExpression doParseExpression(String expressionString, @Nullable ParserContext context)
      throws ParseException {

   try {
      this.expressionString = expressionString;
      Tokenizer tokenizer = new Tokenizer(expressionString);
      this.tokenStream = tokenizer.process();
      this.tokenStreamLength = this.tokenStream.size();
      this.tokenStreamPointer = 0;
      this.constructedNodes.clear();
      SpelNodeImpl ast = eatExpression();
      Assert.state(ast != null, "No node");
      Token t = peekToken();
      if (t != null) {
         throw new SpelParseException(t.startPos, SpelMessage.MORE_INPUT, toString(nextToken()));
      }
      Assert.isTrue(this.constructedNodes.isEmpty(), "At least one node expected");
      return new SpelExpression(expressionString, ast, this.configuration);
   }
   catch (InternalParseException ex) {
      throw ex.getCause();
   }
}

这一行

//        token解析
         this.tokenStream = tokenizer.process();

返回

org.springframework.context.expression.StandardBeanExpressionResolver#evaluate

//              设置类型转换器
               sec.setTypeConverter(new StandardTypeConverter(conversionService));

依赖注入

进入

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

@Override
   public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {、
//    找到自动注入的元数据
      InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
      metadata.checkConfigMembers(beanDefinition);
   }

进入

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
      // Fall back to class name as cache key, for backwards compatibility with custom callers.返回到类名作为缓存键,以便向后兼容自定义调用程序。
      String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
      // Quick check on the concurrent map first, with minimal locking.
      InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
      if (InjectionMetadata.needsRefresh(metadata, clazz)) {
         synchronized (this.injectionMetadataCache) {
            metadata = this.injectionMetadataCache.get(cacheKey);
            if (InjectionMetadata.needsRefresh(metadata, clazz)) {
               if (metadata != null) {
                  metadata.clear(pvs);
               }
//             构建自动准入的元数据
               metadata = buildAutowiringMetadata(clazz);
               this.injectionMetadataCache.put(cacheKey, metadata);
            }
         }
      }
      return metadata;
   }

这一行

//              构建自动准入的元数据
               metadata = buildAutowiringMetadata(clazz);

进入

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
      LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
      Class<?> targetClass = clazz;

      do {
         final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>();

         ReflectionUtils.doWithLocalFields(targetClass, field -> {
//          查找依赖注入注解的属性值
            AnnotationAttributes ann = findAutowiredAnnotation(field);
            if (ann != null) {
               if (Modifier.isStatic(field.getModifiers())) {
                  if (logger.isWarnEnabled()) {
                     logger.warn("Autowired annotation is not supported on static fields: " + field);
                  }
                  return;
               }
//             判断required的值
               boolean required = determineRequiredStatus(ann);
               currElements.add(new AutowiredFieldElement(field, required));
            }
         });

         ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
               return;
            }
            AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
            if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
               if (Modifier.isStatic(method.getModifiers())) {
                  if (logger.isWarnEnabled()) {
                     logger.warn("Autowired annotation is not supported on static methods: " + method);
                  }
                  return;
               }
               if (method.getParameterCount() == 0) {
                  if (logger.isWarnEnabled()) {
                     logger.warn("Autowired annotation should only be used on methods with parameters: " +
                           method);
                  }
               }
               boolean required = determineRequiredStatus(ann);
//             查找方法的属性
               PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
               currElements.add(new AutowiredMethodElement(method, required, pd));
            }
         });

         elements.addAll(0, currElements);
         targetClass = targetClass.getSuperclass();
      }
      while (targetClass != null && targetClass != Object.class);

      return new InjectionMetadata(clazz, elements);
   }

解析完的自动注入元数据会存储到本地缓存中,bean初始化时会调用,这部分的逻辑在bean初始化、依赖注入的部分解析过了

到这里,spring ioc源码解析完了

最后

本次介绍到这里,以上内容仅供参考。

扫码关注

进群讨论

快到碗里来

!

猜你喜欢

转载自my.oschina.net/u/3775437/blog/1813314