Spring源码 18 IOC refresh方法13

Spring IOC 的核心是 AbstractApplicationContextrefresh 方法。
其中一共有 13 个主要方法,这里分析第 13 个:resetCommonCaches

1 AbstractApplicationContext

1-1 清空缓存

resetCommonCaches()
protected void resetCommonCaches() {
    // 清空反射缓存
    ReflectionUtils.clearCache();
    // 清空注解缓存
    AnnotationUtils.clearCache();
    // 清空并发缓存
    ResolvableType.clearCache();
    // 清空类加载器
    CachedIntrospectionResults.clearClassLoader(getClassLoader());
}

1-2 清空反射缓存

ReflectionUtils.clearCache()

2 ReflectionUtils

private static final Map<Class<?>, Method[]> declaredMethodsCache = new ConcurrentReferenceHashMap<>(256);
private static final Map<Class<?>, Field[]> declaredFieldsCache = new ConcurrentReferenceHashMap<>(256);

public static void clearCache() {
   declaredMethodsCache.clear();
   declaredFieldsCache.clear();
}

1 AbstractApplicationContext

1-2 清空注解缓存

AnnotationUtils.clearCache()
public static void clearCache() {
    // 清空类型映射缓存
    AnnotationTypeMappings.clearCache();
    // 清空注解扫描缓存
    AnnotationsScanner.clearCache();
}

3-1 清空类型映射缓存

AnnotationTypeMappings.clearCache()

4 AnnotationTypeMappings

private static final Map<AnnotationFilter, Cache> standardRepeatablesCache = new ConcurrentReferenceHashMap<>();
private static final Map<AnnotationFilter, Cache> noRepeatablesCache = new ConcurrentReferenceHashMap<>();

static void clearCache() {
   standardRepeatablesCache.clear();
   noRepeatablesCache.clear();
}

3 AnnotationUtils

3-1 清空注解扫描缓存

AnnotationsScanner.clearCache()

5 AnnotationsScanner

private static final Map<AnnotatedElement, Annotation[]> declaredAnnotationCache = new ConcurrentReferenceHashMap<>(256);
private static final Map<Class<?>, Method[]> baseTypeMethodsCache = new ConcurrentReferenceHashMap<>(256);

static void clearCache() {
   declaredAnnotationCache.clear();
   baseTypeMethodsCache.clear();
}

1 AbstractApplicationContext

1-2 清空并发缓存

ResolvableType.clearCache()

6 ResolvableType

private static final ConcurrentReferenceHashMap<ResolvableType, ResolvableType> cache = new ConcurrentReferenceHashMap<>(256);

public static void clearCache() {
   cache.clear();
   SerializableTypeWrapper.cache.clear();
}

1 AbstractApplicationContext

1-2 清空类加载器

CachedIntrospectionResults.clearClassLoader(getClassLoader())

7 CachedIntrospectionResults

static final Set<ClassLoader> acceptedClassLoaders = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
static final ConcurrentMap<Class<?>, CachedIntrospectionResults> strongClassCache = new ConcurrentHashMap<>(64);
static final ConcurrentMap<Class<?>, CachedIntrospectionResults> softClassCache = new ConcurrentReferenceHashMap<>(64);

public static void clearClassLoader(@Nullable ClassLoader classLoader) {
   // 判断是否在类加载器下面
   acceptedClassLoaders.removeIf(registeredLoader -> isUnderneathClassLoader(registeredLoader, classLoader));
   strongClassCache.keySet().removeIf(beanClass -> isUnderneathClassLoader(beanClass.getClassLoader(), classLoader));
   softClassCache.keySet().removeIf(beanClass -> isUnderneathClassLoader(beanClass.getClassLoader(), classLoader));
}

7-1 判断是否在类加载器下面

isUnderneathClassLoader(registeredLoader, classLoader)
private static boolean isUnderneathClassLoader(@Nullable ClassLoader candidate, @Nullable ClassLoader parent) {
   if (candidate == parent) {
      return true;
   }
   if (candidate == null) {
      return false;
   }
   ClassLoader classLoaderToCheck = candidate;
   while (classLoaderToCheck != null) {
      classLoaderToCheck = classLoaderToCheck.getParent();
      if (classLoaderToCheck == parent) {
         return true;
      }
   }
   return false;
}

参考

https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click

https://www.bilibili.com/video/BV12Z4y197MU?spm_id_from=333.999.0.0

《Spring源码深度解析(第2版)》

版本

Spring 5.3.15

posted @ 2022-03-14 14:01  天航星  阅读(82)  评论(0编辑  收藏  举报