• 主页
  • 系列总集
  • OpenCV
  • CMake
  • iOS
  • Java
  • 前端
所有文章 关于我

  • 主页
  • 系列总集
  • OpenCV
  • CMake
  • iOS
  • Java
  • 前端

Web框架学习:类加载工具

2016-03-16

Java的类加载机制

Java的代码都是运行在JVM虚拟机中的,使用类加载机制来完成代码的运行,具体内容还不是很了解,但是类加载机制总需要有一个线程来操作,Web框架中的类加载工具就是获取到这个线程,并把框架里的类加载进去.

类加载工具流程

  1. 新建一个HashSet存放Class
  2. 通过File文件目录/jar包/“.class”文件三种方式遍历取出Class
  3. 获取到类加载线程进行加载

Example

package org.smart4j.framework.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smart4j.framework.util.tool.StringUtil;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;


public final class ClassUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClassUtil.class);

    public static Set<Class<?>> getClassSet (String packageName) {
        //init a Classset
        Set<Class<?>> classSet = new HashSet<Class<?>>();
        //loop for find Class
        try {
            Enumeration<URL> urls = getClassLoader().getResources(packageName.replace(".","/"));
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                if (url != null) {
                    String protocol = url.getProtocol();
                    if (protocol.equals("file")) {
                        String packagePath = url.getPath().replaceAll("%20"," ");
                        addClass(classSet, packagePath,packageName);
                    }else if (protocol.equals("jar")) {
                        JarURLConnection jarURLConnection = (JarURLConnection)url.openConnection();
                        if (jarURLConnection != null) {
                            JarFile jarFile = jarURLConnection.getJarFile();
                            if (jarFile != null) {
                                Enumeration<JarEntry> jarEnties = jarFile.entries();
                                while (jarEnties.hasMoreElements()) {
                                    JarEntry jarEntry = jarEnties.nextElement();
                                    String jarEntryName = jarEntry.getName();
                                    if (jarEntryName.endsWith(".class")) {
                                        String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/",".");
                                        doAddClass(classSet,className);
                                    }
                                }
                            }
                        }
                    }
                }

            }
        } catch (IOException e) {
            LOGGER.error("get class set failure", e);
            throw new  RuntimeException(e);
        }
        //return ClassSet
        return classSet;
    }

    private static void doAddClass(Set<Class<?>> classSet, String className) {
        Class<?> cls = loadClass(className, false);
        classSet.add(cls);
    }

    private static void addClass(Set<Class<?>> classSet, String packagePath, final String packageName) {
        final File[] files = new File(packagePath).listFiles(new FileFilter() {
            public boolean accept(File pathname) {
                return (pathname.isFile() && pathname.getName().endsWith(".class"))|| pathname.isDirectory();
            }
        });

        for (File file: files) {
            //Get File name
            String fileName = file.getName();
            //
            if (file.isFile()) {
                String className = fileName.substring(0,fileName.lastIndexOf("."));
                if (StringUtil.isNotEmpty(packageName)) {
                    className = packageName+"."+className;
                }
                doAddClass(classSet, className);
            }else {
                String subPackagePath = fileName;
                if (StringUtil.isNotEmpty(packagePath)) {
                    subPackagePath = packagePath + "/" + subPackagePath;
                }
                String subPackageName = fileName;
                if (StringUtil.isNotEmpty(packageName)) {
                    subPackageName = packageName + "." +subPackageName;
                }
                addClass(classSet, subPackagePath, subPackageName);
            }
        }
    }

    public static Class<?> loadClass(String className, boolean isInitialized) {
        Class<?> cls;
        try {
            cls = Class.forName(className,isInitialized, getClassLoader());
        } catch (ClassNotFoundException e) {
            LOGGER.error("load class failure",e);
            throw new RuntimeException(e);
        }
        return cls;
    }

    public static ClassLoader getClassLoader() {
        return Thread.currentThread().getContextClassLoader();
    }

}
赏

请问老板还招人么(/ω\)

支付宝
微信
  • Java
  • Architecture
  • Tutorial

扫一扫,分享到微信

微信分享二维码
Web框架学习:注解的使用
TCP/IP和Socket的关系
© 2021 Alan Li
Hexo Theme Yilia by Litten
  • 所有文章
  • 关于我

tag:

  • iOS
  • Java
  • Collection
  • Python
  • Shell
  • CMake
  • Memory
  • JavaScript
  • Architecture
  • AnchorPoint
  • Android
  • Web
  • Annotation
  • AFNetworking
  • Window
  • ViewController
  • AutoLayout
  • Dozer
  • CoreAnimation
  • Cycle Retain
  • Block
  • UI
  • IDE
  • FrontEnd
  • CSS
  • Category
  • TableViewCell
  • Security
  • Net
  • JSP
  • Spring
  • C
  • MyBatis
  • Date
  • React
  • GCD
  • UITouch
  • Gesture
  • UIControl
  • Git
  • HTML
  • HTTPS
  • HTTP
  • Servlet
  • Server
  • DataBase
  • MySQL
  • Linux
  • Tutorial
  • Ajax
  • Type
  • JQuery
  • JSON
  • Exception
  • Parameter
  • Reflect
  • Thread
  • Sort
  • KVO
  • MKMapKit
  • Overlay
  • Maven
  • Configure
  • Tips
  • Transaction
  • Swift
  • NavigationBar
  • Nginx
  • Runtime
  • OpenCV
  • Property
  • Playground
  • Protocol
  • Redux
  • ScrollView
  • Session
  • Cookie
  • Shiro
  • Error
  • Singleton
  • RegEx
  • StackView
  • StatusBar
  • Base64
  • Socket
  • TCP
  • IP
  • TextField
  • CALayer
  • UILabel
  • View
  • Animation
  • Xcode
  • Hexo
  • Terminal
  • OC
  • Device
  • Log
  • Image
  • JUnit
  • Oval
  • Archive
  • XSS
  • Compiler
  • Aspect
  • Responder
  • Class
  • FireWall
  • RetainCount
  • Const
  • Frame
  • String
  • Symbols
  • Framework
  • CocoaPods
  • Unity
  • Message
  • Button
  • AuthorizationStatus
  • Struct
  • XCTest
  • NSNotification
  • Contact

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

我写的,大概率是错的。。。。。