java动态编译类⽂件并加载到内存中
  如果你想在动态编译并加载了class后,能够⽤hibernate的数据访问接⼝以⾯向对象的⽅式来操作该class类,请参考这篇博⽂-  所谓动态编译,就是在程序运⾏时产⽣java类,并编译成class⽂件。 
  ⼀、这⾥介绍两种动态编译java⽂件的⽅式。
    第⼀种:使⽤Runtime执⾏javac命令
/**
* 编译java类
* 使⽤Runtime执⾏javac命令
* @param name 类的全限定包名不带后缀例如st.Notice  ⽽不要写成st.Notice.java
* @throws java.io.IOException
*/
public static void javac(String name) throws IOException {
String javaPackageName = place(".",File.separator)+".java";
String javaAbsolutePath = classPath+javaPackageName;
Process process = Runtime().exec("javac -classpath "+ jarAbsolutePath+ " " + javaAbsolutePath);
try {
InputStream errorStream = ErrorStream();
InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line = null;
while ((adLine()) != null){
System.out.println(line);
}
int exitVal = process.waitFor();
System.out.println("Process exitValue: " + exitVal);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
View Code
    第⼆种:使⽤jdk⾃带的rt.jar中的ls包提供的编译器
/**
* 编译java类
* 使⽤rt.jar中的ls包提供的编译器
* @param name 类的全限定包名不带后缀例如st.Notice  ⽽不要写成st.Notice.java
* @throws java.io.IOException
*/
public static void compiler(String name) throws IOException {
String javaPackageName = place(".",File.separator)+".java";
String javaAbsolutePath = classPath+javaPackageName;
JavaCompiler compiler = SystemJavaCompiler();
compiler.run(null,null,null,"-encoding","UTF-8","-classpath",String(),javaAbsolutePath);
}
View Code
  ⼆、使⽤Class.forName("");将class⽂件加载到内存中,并得到该类的class对象
/**
* 动态编译⼀个java源⽂件并加载编译⽣成的class
* @param name 类的全限定包名不带后缀例如st.Notice  ⽽不要写成st.Notice.java
* @throws java.io.IOException
*/
public static Class<?> dynamicLoadClass(String name) throws IOException, ClassNotFoundException {
if (!isClassExist(name)){
compiler(name);
}
if(isJavaExist(name)){
if(!FileUtil.destroyFile(classPath + place(".",File.separator)+".java")){
System.out.println("========================================>>>>删除源⽂件失败!");
}
}
return Class.forName(name);
}
View Code
  以下是全部代码:
package lassloader;
import util.FileUtil;
ls.jar.Main;
ls.JavaCompiler;
ls.ToolProvider;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* desc:⾃定义的类加载器,⽤于实现类的动态加载
*/
public class MyClassLoader extends ClassLoader {
//类路径
private static String classPath ;
private static String jarPrefix;
private static StringBuilder jarAbsolutePath;
static{
classPath = ClassLoader().getResource("").getPath();
classPath = !classPath.startsWith("/")?classPath:classPath.substring(1);//去掉开始位置的/
classPath = dsWith(File.separator)?classPath:classPath+File.separator;
jarPrefix = classPath.substring(0,classPath.lastIndexOf("classes"))+File.separator+"lib"+File.separator;        jarAbsolutePath = new StringBuilder().append(jarPrefix)
.append("hibernate-core-4.2.0.Final.jar;")
.append(jarPrefix).append("hibernate-jpa-2.0-api-1.0.1.Final.jar;")
.append(jarPrefix).append("validation-api-1.0.0.GA.jar;");
}
/**
* 如果⽗的类加载器中都不到name指定的类,
* 就会调⽤这个⽅法去从磁盘上加载⼀个类
* @param name 类的全限定包名不带后缀例如st.Notice  ⽽不要写成st.Notice.java
* @return
* @throws java.io.IOException
*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classBytes = null;
Class<?> clazz = null;
try {
//加载类的字节码
classBytes = loadClassBytes(name);
//将字节码交给JVM
clazz = defineClass(name,classBytes,0,classBytes.length);
if(clazz == null){
throw new ClassNotFoundException(name);
}
} catch (IOException e) {
e.printStackTrace();
}
return clazz;
}
/**
* 加载类的字节码
* @param name 类的全限定包名不带后缀例如st.Notice  ⽽不要写成st.Notice.java
* @return
* @throws java.io.IOException
*/
java replace方法
private byte[] loadClassBytes(String name) throws IOException {
String classPackageName = place(".",File.separator)+".class";
String classAbsolutePath = classPath+classPackageName;
/
/编译java⽂件
javac(name);
byte[] bytes = (classAbsolutePath));
return bytes;
}
/**
* 指定的类的class是否存在
* @param name
* @return
* @throws IOException
*/
public static boolean isClassExist(String name) throws IOException {
String classPackageName = place(".",File.separator)+".class";
return FileUtil.isExists(classPath+classPackageName)?true:false;
}
/**
* 指定的类是否存在
* @param name
* @return
* @throws IOException
*/
public static boolean isJavaExist(String name) throws IOException {
String classPackageName = place(".",File.separator)+".java";
return FileUtil.isExists(classPath+classPackageName)?true:false;
}
/**
* 编译java类
* 使⽤Runtime执⾏javac命令
* @param name 类的全限定包名不带后缀例如st.Notice  ⽽不要写成st.Notice.java
* @throws java.io.IOException
*/
public static void javac(String name) throws IOException {
String javaPackageName = place(".",File.separator)+".java";
String javaAbsolutePath = classPath+javaPackageName;
Process process = Runtime().exec("javac -classpath "+ jarAbsolutePath+ " " + javaAbsolutePath);
try {
InputStream errorStream = ErrorStream();
InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line = null;
while ((adLine()) != null){
System.out.println(line);
}
int exitVal = process.waitFor();
System.out.println("Process exitValue: " + exitVal);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 编译java类
* 使⽤rt.jar中的ls包提供的编译器
* @param name 类的全限定包名不带后缀例如st.Notice  ⽽不要写成st.Notice.java
* @throws java.io.IOException
*/
public static void compiler(String name) throws IOException {
String javaPackageName = place(".",File.separator)+".java";
String javaAbsolutePath = classPath+javaPackageName;
JavaCompiler compiler = SystemJavaCompiler();
compiler.run(null,null,null,"-encoding","UTF-8","-classpath",String(),javaAbsolutePath);
}
/**
* 动态编译⼀个java源⽂件并加载编译⽣成的class
* @param name 类的全限定包名不带后缀例如st.Notice  ⽽不要写成st.Notice.java
* @throws java.io.IOException
*/
public static Class<?> dynamicLoadClass(String name) throws IOException, ClassNotFoundException {
if (!isClassExist(name)){
compiler(name);
}
if(isJavaExist(name)){
if(!FileUtil.destroyFile(classPath + place(".",File.separator)+".java")){
System.out.println("========================================>>>>删除源⽂件失败!");
}
}
return Class.forName(name);
}
public static void main (String[] args){
}
}
View Code

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。