設計一個對接系統,經過動態模型的增刪改觸發業務系統相應服務的調用。模型增刪改方法動態發佈爲WebService服務。WebService服務採用CXF發佈,動態類生成採用Javassist。因爲WebService服務類須要添加WebService相關注解,而國內關於Javassist生成包含註解的動態類介紹少之又少,因而花費一下午研究Javassist接口,終於讓我找到了辦法。java
類註解和方法註解生成流程:web
一、 建立註解Annotation;apache
二、 註解隊列AnnotationsAttribute添加註解Annotation;數組
三、 類ClassFile或方法信息CtMethod.getMethodInfo()添加註解隊列AnnotationsAttribute。app
參數註解生成流程:測試
一、 建立註解二維數組Annotation[][]:第一維對應參數序列,第二維對應註解序列;設計
二、 參數註解屬性ParameterAnnotationsAttribute添加註解二維數組Annotation[][];code
三、 方法信息CtMethod.getMethodInfo()添加參數註解屬性ParameterAnnotationsAttribute。server
1、動態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(); } }
2、動態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(); } }
3、SoapUI測試。
注:反編譯查看Javassist生成的動態類。