設計一個對接系統,通過動態模型的增刪改觸發業務系統相應服務的調用。模型增刪改方法動態發布為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生成的動態類。

