文档章节

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

丰行
 丰行
发布于 2014/09/05 17:01
字数 847
阅读 141
收藏 0

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;

        }


© 著作权归作者所有

丰行
粉丝 1
博文 11
码字总数 2147
作品 0
北京
后端工程师
私信 提问
看看Spring的源码(一)——Bean加载过程

本文发表于我的独立博客:Geeekr 最近几天跟同事聊起Spring的一些问题,对一些地方有些疑问,趁这两天有点空,看看Spring的源码,了解下具体的实现细节。本文基于Spring 4.0.5版本。 首先Web...

gongzili
2014/08/18
0
7
Spring mvc 上下文初始化过程

在软件开发的中,如果某些特性的使用比较普遍,那么这些特性往往可以作为平台特性来实现,通过对这些平台特性进行有效的封装,使其向其他应用开放。正是如此,Spring由于其IOC、AOP、事务处理...

乱舞
2018/06/29
0
0
【Spring】详解Spring中Bean的加载

之前写过bean的解析,这篇来讲讲bean的加载,加载要比bean的解析复杂些, 该文之前在小编原文中有发表过,要看原文的可以直接点击原文查看, 从之前的例子开始,Spring中加载一个bean的方式:...

weknow
2017/04/06
0
1
Spring Boot 启动过程分析

1. Spring Boot 入口——main方法 从上面代码可以看出,Annotation定义(@SpringBootApplication)和类定义(SpringApplication.run)最为耀眼,所以分析 Spring Boot 启动过程,我们就从这两...

徐志毅
2018/05/27
0
0
Spring Boot 1.5.3 源码深入分析

Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架通过约定由于配置的原则,来进行简化配置。Spring Boot致力于在蓬勃发展的...

快乐崇拜007
03/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

浅析大数据 学习大数据后能做什么

大数据时代的到来使得大数据开发人才迎来了前所未有的机遇和挑战!一个绝佳的入行机会摆在了众人面前!于是,很多人都在打听,大数据到底有何应用?可以用来做什么?好程序员今天就为大家作出...

好程序员IT
22分钟前
1
0
C# USB视频人脸检测

此程序基于 虹软人脸识别进行的开发 SDK下载地址:https://ai.arcsoft.com.cn/ucenter/user/reg?utm_source=csdn1&utm_medium=referral 前提条件 从虹软官网下载获取ArcFace引擎应用开发包,...

是哇兴哥棒棒哒
33分钟前
2
0
Vagrant虚拟机硬盘扩容

# 停止虚拟机vagrant halt <machine_name># 进入VirtualBox VMs目录,查看并记录原磁盘uuid,留作后用vboxmanage showhdinfo box-disk1.vmdk# 克隆磁盘,vmdk格式无法调整大小,需要...

sskill
35分钟前
1
0
分布式商业萌芽,银行迎来发展新机遇

01 分布式商业萌芽,银行迎来发展新机遇 金融界:近几年区块链的热度经历了过山车般的转折。目前追逐区块链的资本也开始冷静下来,于此同时,各大商业银行对区块链的研究应用也越来越多。您认...

Java领航员
41分钟前
3
0
Spring系列教程六: Spring jdbcTemplate在Dao中的使用

概念 Spring中的jdbcTemplate的主要作用是实现数据的交互,下面我们就在dao层中如何使用jdbctemplate写测试案例 项目目录如下 基于xml实现jdbctemplate 这里我们使用的是JdbcDaoSupport这个类...

我叫小糖主
44分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部