Javassist注解(Annotation)的使用:CXF WebService動態生成


     設計一個對接系統,通過動態模型的增刪改觸發業務系統相應服務的調用。模型增刪改方法動態發布為WebService服務。WebService服務采用CXF發布,動態類生成采用Javassist。由於WebService服務類需要添加WebService相關注解,而國內關於Javassist生成包含注解的動態類介紹少之又少,於是花費一下午研究Javassist接口,終於讓我找到了辦法。

 

     類注解和方法注解生成流程:

     1、 創建注解Annotation;

     2、 注解隊列AnnotationsAttribute添加注解Annotation;

     3、 類ClassFile或方法信息CtMethod.getMethodInfo()添加注解隊列AnnotationsAttribute。

     參數注解生成流程:

     1、 創建注解二維數組Annotation[][]:第一維對應參數序列,第二維對應注解序列;

     2、 參數注解屬性ParameterAnnotationsAttribute添加注解二維數組Annotation[][];

     3、 方法信息CtMethod.getMethodInfo()添加參數注解屬性ParameterAnnotationsAttribute。

 

一、動態WebService服務生成類。

package com.coshaho.learn.javassist;

import java.io.File;
import java.io.FileOutputStream;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool;
import javassist.bytecode.ParameterAnnotationsAttribute;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.StringMemberValue;

public class DynamicWebserviceGenerator 
{
	public Class<?> createDynamicClazz() throws Exception
	{
		ClassPool pool = ClassPool.getDefault();

		// 創建類
		CtClass cc = pool.makeClass("com.coshaho.learn.DynamicHelloWorld");

		// 創建方法   
	    CtClass ccStringType = pool.get("java.lang.String");
		// 參數:  1:返回類型  2:方法名稱  3:傳入參數類型  4:所屬類CtClass  
		CtMethod ctMethod=new CtMethod(ccStringType,"sayHello",new CtClass[]{ccStringType},cc);  
		ctMethod.setModifiers(Modifier.PUBLIC);  
		StringBuffer body=new StringBuffer();  
		body.append("{");
		body.append("\n    System.out.println($1);");  
		body.append("\n    return \"Hello, \" + $1;");  
		body.append("\n}");  
		ctMethod.setBody(body.toString());
		cc.addMethod(ctMethod);  
		
		ClassFile ccFile = cc.getClassFile();
		ConstPool constPool = ccFile.getConstPool();
		
		// 添加類注解
		AnnotationsAttribute bodyAttr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
		Annotation bodyAnnot = new Annotation("javax.jws.WebService", constPool);
		bodyAnnot.addMemberValue("name", new StringMemberValue("HelloWoldService", constPool));
		bodyAttr.addAnnotation(bodyAnnot);
		
		ccFile.addAttribute(bodyAttr);

		// 添加方法注解
		AnnotationsAttribute methodAttr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
		Annotation methodAnnot = new Annotation("javax.jws.WebMethod", constPool);
		methodAnnot.addMemberValue("operationName", new StringMemberValue("sayHelloWorld", constPool));
		methodAttr.addAnnotation(methodAnnot);
		
		Annotation resultAnnot = new Annotation("javax.jws.WebResult", constPool);
		resultAnnot.addMemberValue("name", new StringMemberValue("result", constPool));
		methodAttr.addAnnotation(resultAnnot);
		
		ctMethod.getMethodInfo().addAttribute(methodAttr);
		
		// 添加參數注解
		ParameterAnnotationsAttribute parameterAtrribute = new ParameterAnnotationsAttribute(
				constPool, ParameterAnnotationsAttribute.visibleTag);
	    Annotation paramAnnot = new Annotation("javax.jws.WebParam", constPool);
	    paramAnnot.addMemberValue("name", new StringMemberValue("name",constPool));
	    Annotation[][] paramArrays = new Annotation[1][1];
	    paramArrays[0][0] = paramAnnot;
	    parameterAtrribute.setAnnotations(paramArrays);
	    
	    ctMethod.getMethodInfo().addAttribute(parameterAtrribute);
		
		//把生成的class文件寫入文件
		byte[] byteArr = cc.toBytecode();
		FileOutputStream fos = new FileOutputStream(new File("D://DynamicHelloWorld.class"));
		fos.write(byteArr);
		fos.close();
		
		return cc.toClass();
	}
}

二、動態WebService服務發布。

package com.coshaho.learn.javassist;

import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;

public class DynamicWebServiceServer 
{
    public static void main(String[] args) throws Exception
    {
        DynamicWebserviceGenerator javassistLearn = new DynamicWebserviceGenerator();
        Class<?> webservice = javassistLearn.createDynamicClazz();
        
        JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();
        
        // Web服務的地址
        factoryBean.setAddress("http://localhost:8081/dynamicHello");

        // Web服務對象調用接口
        factoryBean.setServiceClass(webservice);
        Server server = factoryBean.create();
        server.start();
    }
}

三、SoapUI測試。

注:反編譯查看Javassist生成的動態類。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM