首页 > 代码库 > Java 动态的创建注入代码,注入方法给类或者接口并通过反射调用

Java 动态的创建注入代码,注入方法给类或者接口并通过反射调用

1、将要被注入的类:

/*																																							
 * 文 件 名:  JNAUtil.java																																							
 * 版    权:  Sunny Technologies Co., Ltd. Copyright YYYY-YYYY,  All rights reserved																																							
 * 描    述:  <描述>																																							
 * 修 改 人:  L.Hao																																							
 * 修改时间:  2014-11-11																																							
 * 跟踪单号:  <跟踪单号>																																							
 * 修改单号:  <修改单号>																																							
 * 修改内容:  <修改内容>																																							
 */																					
package com.test;																					
																					
import java.util.Arrays;																					
import java.util.List;																					
																					
import com.fms.xx.model.ParamBean;																				
import com.sun.jna.Native;																					
																					
/**																																							
 * <一句话功能简述>																																							
 * <功能详细描述>																																							
 * 																																							
 * @author  L.Hao																																							
 * @version  [版本号, 2014-11-11]																																							
 * @see  [相关类/方法]																																							
 * @since  [产品/模块版本]																																							
 */																					
public class JNAUtil																					
{	
    //Dll文件路径
    public String filePath ;																					
    																					
    public JNAUtil(String filePath)																					
    {																					
        this.filePath = filePath;																					
    }																					
    																					
public double[] XT(List<ParamBean> parameterList, double[] arr)	
{	
  CLibrary INSTANCE = (CLibrary)Native.loadLibrary(filePath,CLibrary.class);	
  int num = 0;	
  INSTANCE.XT(  Double.valueOf(parameterList.get(num++).getParamValue()),	
  Double.valueOf(parameterList.get(num++).getParamValue()),	
  Double.valueOf(parameterList.get(num++).getParamValue()),	
  arr);	
  return arr;	
}	
}

2、将要被注入的接口

/*																																				
\ * 文 件 名:  CLibrary.java																																				
 * 版    权:  Sunny Technologies Co., Ltd. Copyright YYYY-YYYY,  All rights reserved																																				
 * 描    述:  <描述>																																				
 * 修 改 人:  L.Hao																																				
 * 修改时间:  2014-11-11																																				
 * 跟踪单号:  <跟踪单号>																																				
 * 修改单号:  <修改单号>																																				
 * 修改内容:  <修改内容>																																				
 */																																		
package com.test;																																		
																																		
import com.sun.jna.Library;																																		
																																		
/**																																				
 * <一句话功能简述>																																				
 * <功能详细描述>																																				
 * 																																				
 * @author  L.Hao																																				
 * @version  [版本号, 2014-11-11]																																				
 * @see  [相关类/方法]																																				
 * @since  [产品/模块版本]																																				
 */																																		
public interface CLibrary extends Library																																		
{																								
   														
   public void XT(double FLJ,double XTT,double FLK,double ARR[]);	
}

3,注入动态代码并调用

/*
 * 文 件 名:  WriteJavaFile.java
 * 版    权:  Sunny Technologies Co., Ltd. Copyright YYYY-YYYY,  All rights reserved
 * 描    述:  <描述>
 * 修 改 人:  L.Hao
 * 修改时间:  2014-11-15
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package com.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;

import com.fms.xx.common.FunctionParam;
import com.fms.xx.model.ParamBean;

/**
 * 写Java文件
 * <功能详细描述>
 * 
 * @author  L.Hao
 * @version  [版本号, 2014-11-15]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class WriteJavaFile
{
    private static String filePath = "F:\\Workspaces\\MyEclipse10\\xxcalculate\\src\\com\\test\\CLibrary.java";
    
    private static String filePath_JNAUtil = "F:\\Workspaces\\MyEclipse10\\xxcalculate\\src\\com\\test\\JNAUtil.java";
    
    private static String CHFile = "F:\\soft\\apache-tomcat-7.0.52\\webapps\\xxcalculate\\upload\\141112212749\\SharedLib.h";
    
    /** <一句话功能简述>
     * <功能详细描述>
     * @param args [参数说明]
     * 
     * @return void [返回类型说明]
     * @throws Exception 
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public static void main(String[] args) throws Exception
    {
        //当前类的路径
        System.out.println("当前类的路径:"+new File("").getAbsolutePath());
        //创建文件
        createFile(filePath);
        //读接口CLibrary文件
        String cLibraryFileContent = readFile(filePath);
        
        List<FunctionParam> params = parseHfile(CHFile);
        //待拼接的内容
        String appendContent = spliceCLibraryString(params);
        //写文件(如果已经存在就不拼接了)
        if(!cLibraryFileContent.trim().replaceAll("\\s*", "").contains(appendContent.trim().replaceAll("\\s*", ""))){
            WriteStringToFile(filePath, cLibraryFileContent, appendContent);
        }
        
        //读接口JNAUtil文件
        String jNAUtilFileContent = readFile(filePath_JNAUtil);
        
        appendContent = spliceJNAUtilString(params);
        //写文件(如果已经存在就不拼接了)
        if(!jNAUtilFileContent.trim().replaceAll("\\s*", "").contains(appendContent.trim().replaceAll("\\s*", ""))){
            WriteStringToFile(filePath_JNAUtil, jNAUtilFileContent, appendContent);
        }
        
        String filePath = "F:\\Workspaces\\MyEclipse10\\xxcalculate\\src\\com\\test";
        String sourceDir = "F:\\Workspaces\\MyEclipse10\\xxcalculate\\src\\com\\test";
        String targetDir = "F:\\soft\\apache-tomcat-7.0.52\\webapps\\xxcalculate\\WEB-INF\\classes";
        
        boolean result = compiler(filePath, sourceDir, targetDir);
        List<ParamBean> parames = new ArrayList<ParamBean>();
        //ParamBean(String paramCode, String paramName, String paramValue, String paramType)
        parames.add(new ParamBean("FLJ", "空气密度", "0.42", "double"));
        parames.add(new ParamBean("XTT", "空气密度", "0.3", "double"));
        parames.add(new ParamBean("FLK", "空气密度", "0.2", "double"));
        double[] arr = new double[4];
        //编译成功,开始计算
        if (result)
        {
            reflectCall(parames,arr);
        }
    }
    
    /**
     * 反射调用生成的文件
     * <功能详细描述>
     * @param parames
     * @param arr [参数说明]
     * 
     * @return void [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public static void reflectCall(List<ParamBean> parames, double[] arr)
    {
        try
        {
            Constructor<?> conststr = Class.forName("com.test.JNAUtil")
                    .getDeclaredConstructor(new Class[] { String.class });
            conststr.setAccessible(true);
            Object bl = conststr.newInstance(new Object[] { "F:\\soft\\apache-tomcat-7.0.52\\webapps\\xxcalculate\\upload\\141112212749\\SharedLib.dll" });
            
            Class<? extends Object> clazz = bl.getClass();
            
            Method method = clazz.getDeclaredMethod("XT",
                    List.class,
                    double[].class);
            
            method.invoke(bl, parames, arr);
            System.out.println("计算结果:" + Arrays.toString(arr));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    
    // 创建单个文件
    public static boolean createFile(String filePath)
    {
        File file = new File(filePath);
        if (file.exists())
        {// 判断文件是否存在
            System.out.println("目标文件已存在" + filePath);
            //file.delete();
            return false;
        }
        if (filePath.endsWith(File.separator))
        {// 判断文件是否为目录
            System.out.println("目标文件不能为目录!");
            return false;
        }
        if (!file.getParentFile().exists())
        {// 判断目标文件所在的目录是否存在
         // 如果目标文件所在的文件夹不存在,则创建父文件夹
            System.out.println("目标文件所在目录不存在,准备创建它!");
            if (!file.getParentFile().mkdirs())
            {// 判断创建目录是否成功
                System.out.println("创建目标文件所在的目录失败!");
                return false;
            }
        }
        try
        {
            if (file.createNewFile())
            {// 创建目标文件
                System.out.println("创建文件成功:" + filePath);
                return true;
            }
            else
            {
                System.out.println("创建文件失败!");
                return false;
            }
        }
        catch (IOException e)
        {// 捕获异常
            e.printStackTrace();
            System.out.println("创建文件失败!" + e.getMessage());
            return false;
        }
    }
    
    /**
     * 读取指定文件的内容
     * 将指定文件的内容读入到StringBuffer中
     * @param filePath
     * @return [参数说明]
     * 
     * @return String [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public static String readFile(String filePath)
    {
        File file = new File(filePath);
        BufferedReader reader = null;
        StringBuffer sb = new StringBuffer();
        try
        {
            //System.out.println("以行为单位读取文件内容,一次读一整行:");
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            //int line = 1;
            // 一次读入一行,直到读入null为文件结束
            while ((tempString = reader.readLine()) != null)
            {
                sb.append(tempString).append("\t\n");
                
            }
            reader.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return sb.toString();
    }
    
    /**
     * 将字符串写入指定文件
     * 在已有文件内容的基础上写入新内容
     * @param filePath  文件路径
     * @param oldContent 已有内容
     * @param newContent 新加内容
     * 
     * @return void [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public static void WriteStringToFile(String filePath, String oldContent,
            String newContent)
    {
        StringBuffer strBuffer = new StringBuffer();
        try
        {
            oldContent = oldContent.substring(0, oldContent.lastIndexOf("}"));
            strBuffer.append(oldContent);
            strBuffer.append(newContent);
            strBuffer.append("}");
            // 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件   
            FileWriter writer = new FileWriter(filePath, false);
            writer.write(strBuffer.toString());
            writer.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    
    /**
     * 文件编译
     * 调用java编译器编译java文件
     * @param filePath  文件路径
     * @param sourceDir 源文件所在目录
     * @param targetDir 目标文件所在目录
     * 
     * @return boolean [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    @SuppressWarnings("rawtypes")
    public static boolean compiler(String filePath, String sourceDir,
            String targetDir)
    {
        boolean compilerResult = false;
        try
        {
            DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
            compilerResult = DynamicCompilerUtil.compiler(filePath,
                    sourceDir,
                    targetDir,
                    diagnostics);
            if (compilerResult)
            {
                System.out.println("编译成功");
            }
            else
            {
                System.out.println("编译失败");
                for (Diagnostic diagnostic : diagnostics.getDiagnostics())
                {
                    System.out.println(diagnostic.getMessage(null));
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return compilerResult;
    }
    
    /**
     * <一句话功能简述>
     * <功能详细描述>
     * @param fileName
     * @return [参数说明]
     * 
     * @return List<FunctionParam> [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public static List<FunctionParam> parseHfile(String fileName)
    {
        Map<String, List<FunctionParam>> map = ReadHFile.parseH(fileName);
        
        List<FunctionParam> params = (List<FunctionParam>) map.get("params");
        
        return params;
    }
    
    /**
     * 拼接接口文件内容
     * <功能详细描述>
     * @param params
     * @return [参数说明]
     * 
     * @return String [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public static String spliceCLibraryString(List<FunctionParam> params)
    {
        StringBuffer strBuffer = new StringBuffer();
        strBuffer.append("   public void ");
        strBuffer.append(params.get(0).getMethodName()).append("(");
        for (FunctionParam functionParam : params)
        {
            strBuffer.append(functionParam.getParamType())
                    .append(" ")
                    .append(functionParam.getParamName())
                    .append(",");
        }
        strBuffer.replace(strBuffer.length() - 1, strBuffer.length(), "");
        strBuffer.append(");").append("\t\n");
        return strBuffer.toString();
    }
    
    /**
     * 拼接被调用类内容
     * <功能详细描述>
     * @param params
     * @return [参数说明]
     * 
     * @return String [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public static String spliceJNAUtilString(List<FunctionParam> params)
    {
        String methodName = params.get(0).getMethodName();
        StringBuffer strBuffer = new StringBuffer();
        strBuffer.append("public double[] ");
        strBuffer.append(methodName)
                .append("(List<ParamBean> parameterList, double[] arr)")
                .append("\t\n");
        strBuffer.append("{").append("\t\n");
        strBuffer.append(" CLibrary INSTANCE = (CLibrary)Native.loadLibrary(filePath,CLibrary.class);")
                .append("\t\n");
        strBuffer.append("  int num = 0;").append("\t\n");
        strBuffer.append("  INSTANCE.").append(methodName).append("(");
        
        int count = params.size();
        
        int num = 0;
        for (FunctionParam functionParam : params)
        {
            num++;
            if (count == num)
            {
                continue;
            }
            if ("double".equalsIgnoreCase(functionParam.getParamType()))
            {
                strBuffer.append("    Double.valueOf(parameterList.get(num++).getParamValue()),")
                        .append("\t\n");
            }
            if ("char".equalsIgnoreCase(functionParam.getParamType()))
            {
                strBuffer.append("    parameterList.get(num++).getParamValue().toCharArray(),")
                        .append("\t\n");
            }
        }
        strBuffer.append("  arr);").append("\t\n");
        strBuffer.append("  return arr;").append("\t\n");
        strBuffer.append("}").append("\t\n");
        return strBuffer.toString();
    }
}


Java 动态的创建注入代码,注入方法给类或者接口并通过反射调用