Springbootダイナミックパブリッシュインタフェースダイナミックコンパイルclass

5169 ワード

1.velocityテンプレートによるJavaテンプレートの生成
            2.コマンドラインによるプロセス=Runtime.getRuntime().exec(commod);動的にclassにコンパイル
            3.classを通るforName(「パッケージクラス名」)はバイトコードをロードしてclassオブジェクトになります
            4.SpringのApplicationContextを取得して手動でRequestMappingHandlerMappingにmappingを登録し、動的なパブリケーションを完了します.
巨大な穴:https://github.com/michaelliao/compiler2016年にメンテナンスされていないプロジェクトに属し、issue上のspring bootではエラーが報告されるため、メモリを介してファイルを作成する方法を放棄し、新しく生成されたJavaクラスがjdk以外のサードパーティコンポーネントに依存する必要がある場合はコンパイルエラーが発生します.この文章はspring bootではコンパイルに成功しません.この文章は複雑すぎて、classloadをカスタマイズする必要はありません.
ステップ1:contentがテンプレートによって生成されたJavaクラスのコンテンツであるjavaファイルを生成します.ここではテンプレートの作成を省略します.
 String content = "package com.test;public class TestDemo{private String studentId;public String getStudentId()
 {return this.studentId;}public void setStudentId(String studentId){this.studentId = studentId;}}";
        String fileName ="D/...TestDemo.java";
        File file = new File(fileName);
        FileWriter fileWriter = new FileWriter(file);
        fileWriter.write(content);
        fileWriter.flush();
        fileWriter.close();
		

ステップ2classファイルのコンパイル
  /**
     *   java 
     *   Runtime  javac  
     * @param packageAndClass                com.test.Notice       com.test.Notice.java
     * @throws java.io.IOException
     */
    public static void javac(String packageAndClass,String jarAbsolutePath) throws IOException {
    
      
        Process process = Runtime.getRuntime().exec("javac -cp"+ jarAbsolutePath+ " " + packageAndClass);
        try {
            InputStream errorStream = process.getErrorStream();
            InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String line = null;
            while ((line=bufferedReader.readLine()) != null){
                System.out.println(line);
            }
//    0,       ,    CMD  
            int exitVal = process.waitFor();
            System.out.println("Process exitValue: " + exitVal);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

ステップ3:classファイルからクラスオブジェクトおよびバイトコード配列を取得する
//classAbsolutePath     Java    class    ,        ,class    Java         
        byte[] bytes = Files.readAllBytes(Paths.get(classAbsolutePath));
//  class.forName("   ")       

 
ステップ4:springに注入
/**
	* controlCenter(   RequestMappingHandlerMapping   、  、  Mapping  )    
	* @param   Class       Class    
	* @param  ApplicationContext spring    
	* @param  type 1   2   3  
	 * @throws Exception 
	 * @throws IllegalAccessException 
	* @Exception         
	* @since  CodingExample Ver(      ) 1.1
	* @author jiaxiaoxian
	 */
	public static void controlCenter(Class> controllerClass,ApplicationContext  Context,Integer type) throws IllegalAccessException, Exception{
		//  RequestMappingHandlerMapping 
		RequestMappingHandlerMapping requestMappingHandlerMapping=(RequestMappingHandlerMapping) Context.getBean("requestMappingHandlerMapping");
		Method getMappingForMethod =ReflectionUtils.findMethod(RequestMappingHandlerMapping.class, "getMappingForMethod",Method.class,Class.class);
		//         
		getMappingForMethod.setAccessible(true);
		//       
		Method[] method_arr = controllerClass.getMethods();
		for (Method method : method_arr) {
		        //          RequestMapping
			if (method.getAnnotation(RequestMapping.class) != null) {
			        //     RequestMappingInfo 
				RequestMappingInfo mappingInfo = (RequestMappingInfo) getMappingForMethod.invoke(requestMappingHandlerMapping, method,controllerClass);
				if(type == 1){
				        //  
					registerMapping(requestMappingHandlerMapping, mappingInfo, controllerClass, method);
				}else if(type == 2){
				        //    
					unRegisterMapping(requestMappingHandlerMapping, mappingInfo);
					registerMapping(requestMappingHandlerMapping, mappingInfo, controllerClass, method);
				}else if(type == 3){
					unRegisterMapping(requestMappingHandlerMapping, mappingInfo);
				}
				
			}
		}
	}
	
	/**
	 * 
	* registerMapping(  mapping spring   )    
	* @param   requestMappingHandlerMapping    
	* @Exception         
	* @since  CodingExample Ver(      ) 1.1
	* @author jiaxiaoxian
	 */
	public static void registerMapping(RequestMappingHandlerMapping requestMappingHandlerMapping,RequestMappingInfo mappingInfo, Class> controllerClass, Method method) throws Exception, IllegalAccessException{
		requestMappingHandlerMapping.registerMapping(mappingInfo, controllerClass.newInstance(),method);
	}
	
	/**
	 * 
	* unRegisterMapping(spring     mapping)    
	* @param   requestMappingHandlerMapping    
	* @Exception         
	* @since  CodingExample Ver(      ) 1.1
	* @author jiaxiaoxian
	 */
	public static void unRegisterMapping(RequestMappingHandlerMapping requestMappingHandlerMapping,RequestMappingInfo mappingInfo) throws Exception, IllegalAccessException{
		requestMappingHandlerMapping.unregisterMapping(mappingInfo);
	}