您的位置:首页 > 编程语言 > Java开发

Javassist注解(Annotation)的使用:CXF WebService动态生成

2016-01-06 14:41 281 查看
设计一个对接系统,通过动态模型的增删改触发业务系统相应服务的调用。模型增删改方法动态发布为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生成的动态类。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: