Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

印次:2019 年 5 月第 3 次印刷 的几处修改建议 #98

Open
ReionChan opened this issue May 27, 2022 · 0 comments
Open

印次:2019 年 5 月第 3 次印刷 的几处修改建议 #98

ReionChan opened this issue May 27, 2022 · 0 comments

Comments

@ReionChan
Copy link

《Spring Boot 编程思想》勘误

  • 所购书籍印刷批次信息
    • 版次: 2019 年 3 月第 1 版
    • 印次: 2019 年 5 月第 3 次印刷

【第 71 页】 Servlet 规范 Jetty 容器版本支持

Servlet 规范			Jetty
- 4.0							 9.x
+ 4.0							10.x

- 3.1							8.x
+ 3.1							9.x

- 3.0							7.x
+ 3.0							8.x

【第 153、154 页】 几处 元素 应为 属性

  • 第三个表格
Spring 注解		场景说明
- @Primary		替换 XML 元素 <bean primary="true|false">
+ @Primary		替换 XML 属性 <bean primary="true|false">

- @Role				替换 XML 元素 <bean role="...">
+ @Role				替换 XML 属性 <bean role="...">
  • 第六个表格
Spring 注解		场景说明
- @PostConstruct		替换 XML 元素 <bean init-method="..."> 或 InitializingBean
+ @PostConstruct		替换 XML 属性 <bean init-method="..."> 或 InitializingBean

- @PreDestroy				替换 XML 元素 <bean destroy-method="..."> 或 DisposableBean
+ @PreDestroy				替换 XML 属性 <bean destroy-method="..."> 或 DisposableBean

【第 159 页】排版问题 scan 前多了空格

  • 正文第一段第一行:
- 并使用 <context:component- scan /> 元素扫
+ 并使用 <context:component-scan /> 元素扫

【第 209 页】AnnotationAttributes 扩展 LinkedHashMap 目的论述存在歧义

  • 正文第一段第三行:
- 又要确保其顺序保持与属性方法声明一致。
+ 又要确保其顺序保持与 Class#getDeclaredMethods 方法返回的数组顺序一致。

  属性方法声明 :有人(包括我)误认为是 注解类的属性方法源代码里声明顺序

  除上面绿色修改建议外,另一完全使用中文描述候选建议方案:

+ 又要确保其顺序保持与运行时反射加载的属性方法数组顺序一致。
  • 修改原由

​ 当把 属性方法声明顺序 误认为是属性方法在源代码中声明的顺序时,实际代码验证这种理解是错的。而真正 属性方法声明顺序 是与注解的 Class 对象调用 getDeclaredMethods() 方法返回的 Method[]数组顺序一致。

​ 下面的源代码可以支持这一论点:

public abstract class AnnotationUtils {
  
  static AnnotationAttributes retrieveAnnotationAttributes(@Nullable Object annotatedElement, Annotation annotation,
        boolean classValuesAsString, boolean nestedAnnotationsAsMap) {

      Class<? extends Annotation> annotationType = annotation.annotationType();
      AnnotationAttributes attributes = new AnnotationAttributes(annotationType);
			// Class#getDeclaredMethods() 方法数组顺序借由 List<Method> 传递到此
      for (Method method : getAttributeMethods(annotationType)) {
        try {
          Object attributeValue = method.invoke(annotation);
          Object defaultValue = method.getDefaultValue();
          if (defaultValue != null && ObjectUtils.nullSafeEquals(attributeValue, defaultValue)) {
            attributeValue = new DefaultValueHolder(defaultValue);
          }
          // attributes 由于是 LinkedHashMap 的扩展,故此处 put 插入顺序得以和 Class#getDeclaredMethods() 保持一致
          attributes.put(method.getName(),
              adaptValue(annotatedElement, attributeValue, classValuesAsString, nestedAnnotationsAsMap));
        }
        catch (Throwable ex) {
          if (ex instanceof InvocationTargetException) {
            Throwable targetException = ((InvocationTargetException) ex).getTargetException();
            rethrowAnnotationConfigurationException(targetException);
          }
          throw new IllegalStateException("Could not obtain annotation attribute value for " + method, ex);
        }
      }

      return attributes;
    }

  static List<Method> getAttributeMethods(Class<? extends Annotation> annotationType) {
      // 第一次执行跳过缓存
    	List<Method> methods = attributeMethodsCache.get(annotationType);
      if (methods != null) {
        return methods;
      }
			
      methods = new ArrayList<>();
      // 此处收集的属性方法列表,顺序来源于 Class#getDeclaredMethods()
      for (Method method : annotationType.getDeclaredMethods()) {
        if (isAttributeMethod(method)) {
          ReflectionUtils.makeAccessible(method);
          methods.add(method);
        }
      }

      attributeMethodsCache.put(annotationType, methods);
      return methods;
    }
}

​ 而之所以属性方法顺序不会与源代码中属性方法顺序一致,根源是 Class#getDeclaredMethods 方法返回的 Method[] 数组元素顺序的不确定性。

​ 以下引用该方法的 JavaDoc 注释:

The elements in the returned array are not sorted and are not in any particular order.

/**
     * <p> The elements in the returned array are not sorted and are not in any
     * particular order.
     *
     * @jls 8.2 Class Members
     * @jls 8.4 Method Declarations
     * @since JDK1.1
     */
    @CallerSensitive
    public Method[] getDeclaredMethods() throws SecurityException {
        ...
    }

【第 294 页】词语颠倒

  • 正文最后一行:
- 该引导类在启动秒后数,抛出以下异常:
+ 该引导类在启动数秒后,抛出以下异常:

【第 330 页】单词黏连、拆开后中间加一个 “的” 表示 @AutoConfigureBefore @AutoConfigureAfter 两者的 name 属性

  • 正文倒数第三行:
- 建议尽可能地使用 @AutoConfigureBefore 或 @AutoConfigureAftername() 属性方法,
+ 建议尽可能地使用 @AutoConfigureBefore 或 @AutoConfigureAfter 的 name()属性方法,

【第 538 页】缺少 Boot 单词

  • 正文最后一行:
- Spring 1.4 开始,将它们重构至
+ Spring Boot 1.4 开始,将它们重构至

【第 558 页】SpringApplication 的 run(String... ) 方法调用 handleRunFailure 多了一个参数

public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.started();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
			context = createAndRefreshContext(listeners, applicationArguments);
			afterRefresh(context, applicationArguments);
			listeners.finished(context, null);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass)
						.logStarted(getApplicationLog(), stopWatch);
			}
			return context;
		}
		catch (Throwable ex) {
      // 此处多了 analyzers 参数
			// handleRunFailure(context, listeners, analyzers, ex);
      
      // 应替换为下面的调用
      handleRunFailure(context, listeners, ex);
			throw new IllegalStateException(ex);
		}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant