Spring 初始化时根据配置文件中class加载类的过程

Spring 初始化时根据配置文件中class加载类的过程

        /** Suffix for array class names: "[]" */

        public static final String ARRAY_SUFFIX = "[]";

        /** Prefix for internal array class names: "[" */

        private static final String INTERNAL_ARRAY_PREFIX = "[";

        

        /** Prefix for internal non-primitive array class names: "[L" */

        private static final String NON_PRIMITIVE_ARRAY_PREFIX = "[L";

        

        /** The CGLIB class separator character "$$" */

        public static final String CGLIB_CLASS_SEPARATOR = "$$";

        

        /**

        * Map with primitive wrapper type as key and corresponding primitive

        * type as value, for example: Integer.class -> int.class.

        */

        private static final Map<Class<?>, Class<?>> primitiveWrapperTypeMap = new HashMap<Class<?>, Class<?>>(8);

        /**

        * Map with primitive type as key and corresponding wrapper

        * type as value, for example: int.class -> Integer.class.

        */

        private static final Map<Class<?>, Class<?>> primitiveTypeToWrapperMap = new HashMap<Class<?>, Class<?>>(8);

        /**

        * Map with primitive type name as key and corresponding primitive

        * type as value, for example: "int" -> "int.class".

        */

        private static final Map<String, Class<?>> primitiveTypeNameMap = new HashMap<String, Class<?>>(32);

        /**

        * Map with common "java.lang" class name as key and corresponding Class as value.

        * Primarily for efficient deserialization of remote invocations.

        */

        private static final Map<String, Class<?>> commonClassCache = new HashMap<String, Class<?>>(32);

        

        static {

            //初始化基本类型

             primitiveWrapperTypeMap.put(Boolean.class, boolean.class);

             primitiveWrapperTypeMap.put(Byte.class, byte.class);

             primitiveWrapperTypeMap.put(Character.class, char.class);

             primitiveWrapperTypeMap.put(Double.class, double.class);

             primitiveWrapperTypeMap.put(Float.class, float.class);

             primitiveWrapperTypeMap.put(Integer.class, int.class);

             primitiveWrapperTypeMap.put(Long.class, long.class);

             primitiveWrapperTypeMap.put(Short.class, short.class);

            

             for (Map.Entry<Class<?>, Class<?>> entry : primitiveWrapperTypeMap.entrySet()) {

                 primitiveTypeToWrapperMap.put(entry.getValue(), entry.getKey());

                 registerCommonClasses(entry.getKey());

            }

        

             Set<Class<?>> primitiveTypes = new HashSet<Class<?>>(32);

             primitiveTypes.addAll(primitiveWrapperTypeMap.values());

             primitiveTypes.addAll(Arrays.asList(new Class<?>[] {

             boolean[].class, byte[].class, char[].class, double[].class,

             float[].class, int[].class, long[].class, short[].class}));

                原始类型中,添加void类型

             primitiveTypes.add(void.class);

        

             for (Class<?> primitiveType : primitiveTypes) {

                 primitiveTypeNameMap.put(primitiveType.getName(), primitiveType);

             }

            

            //将原始类型注册在HashMap中缓存起来

             registerCommonClasses(Boolean[].class, Byte[].class, Character[].class, Double[].class,

             Float[].class, Integer[].class, Long[].class, Short[].class);

             registerCommonClasses(Number.class, Number[].class, String.class, String[].class,

             Object.class, Object[].class, Class.class, Class[].class);

        

             registerCommonClasses(Throwable.class, Exception.class, RuntimeException.class,

             Error.class, StackTraceElement.class, StackTraceElement[].class);

        }


        /**

        * Register the given common classes with the ClassUtils cache.

        */

        private static void registerCommonClasses(Class<?>... commonClasses) {

             for (Class<?> clazz : commonClasses) {

                 commonClassCache.put(clazz.getName(), clazz);

            }

        }

    

        //根据类名判断该类是否在原始类型中。如果是,则直接返回对应的class类型

        public static Class<?> resolvePrimitiveClassName(String name) {

             Class<?> result = null;

             // Most class names will be quite long, considering that they

             // SHOULD sit in a package, so a length check is worthwhile.

             if (name != null && name.length() <= 8) {

                 // Could be a primitive - likely.

                  result = primitiveTypeNameMap.get(name);

             }

             return result;

        }


        public static Class<?> forName(String name, ClassLoader classLoader) throws ClassNotFoundException, LinkageError {

             Assert.notNull(name, "Name must not be null");

            

             Class<?> clazz = resolvePrimitiveClassName(name);

             //如果根据className在原始类型的Map中没有找到。则在公共缓存Map中查询

             if (clazz == null) {

                  clazz = commonClassCache.get(name);

             }

            //如果在公共缓存Map中找到。则直接返回对应的class

             if (clazz != null) {

                 return clazz;

             }

            //校验bean的clas属性值是否为数组对象。比如:java.lang.String[]

             // "java.lang.String[]" style arrays

             if (name.endsWith(ARRAY_SUFFIX)) {

                //如果是,则将类名后的“[]”方括号截去,返回java.lang.String,递归查找类名,找到后,将Class类型转换为数组。

                 String elementClassName = name.substring(0, name.length() - ARRAY_SUFFIX.length());

                 Class<?> elementClass = forName(elementClassName, classLoader);

                 return Array.newInstance(elementClass, 0).getClass();

             }

            //校验bean的class属性值是否为数组对象的二进制表示。比如:[Ljava.lang.String.

            //如果是,则将值的“[L”部分截去,递归查找类名,找到后,将对应的Class类型转换为数组

             // "[Ljava.lang.String;" style arrays

             if (name.startsWith(NON_PRIMITIVE_ARRAY_PREFIX) && name.endsWith(";")) {

                 String elementName = name.substring(NON_PRIMITIVE_ARRAY_PREFIX.length(), name.length() - 1);

                 Class<?> elementClass = forName(elementName, classLoader);

                 return Array.newInstance(elementClass, 0).getClass();

             }

            //校验是class属性值是否为二维数组

             // "[[I" or "[[Ljava.lang.String;" style arrays

             if (name.startsWith(INTERNAL_ARRAY_PREFIX)) {

                 String elementName = name.substring(INTERNAL_ARRAY_PREFIX.length());

                 Class<?> elementClass = forName(elementName, classLoader);

                 return Array.newInstance(elementClass, 0).getClass();

             }

            //获取classLoader。

             ClassLoader classLoaderToUse = classLoader;

             if (classLoaderToUse == null) {

                    //如果classLoader为空,则获取默认的classLoader对象。

                  classLoaderToUse = getDefaultClassLoader();

             }

             try {

                  return classLoaderToUse.loadClass(name);//返回加载后的类

             }

             catch (ClassNotFoundException ex) {

                  //用于处理内部类的情况。

                 int lastDotIndex = name.lastIndexOf('.');

                 if (lastDotIndex != -1) {

                        //组装内部类的名字。

                      String innerClassName = name.substring(0, lastDotIndex) + '$' + name.substring(lastDotIndex + 1);

                      try {

                          return classLoaderToUse.loadClass(innerClassName);

                      }

                      catch (ClassNotFoundException ex2) {

                           // swallow - let original exception get through

                      }

                 }

             throw ex;

             }

        }

        

        

        //获取默认的classLoader

        public static ClassLoader getDefaultClassLoader() {

             ClassLoader cl = null;

             try {

                  cl = Thread.currentThread().getContextClassLoader();

             }

             catch (Throwable ex) {

                  // Cannot access thread context ClassLoader - falling back to system class loader...

             }

             if (cl == null) {

                 // No thread context class loader -> use class loader of this class.

                 cl = ClassUtils.class.getClassLoader();

             }

             return cl;

        }


转载于:https://my.oschina.net/fxservice/blog/310665

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值