`
m635674608
  • 浏览: 4905136 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

jaxb动态修改注解-类加载器

    博客分类:
  • java
 
阅读更多

最近项目用到jaxb解析xml文件。需要定义一个javaBean模型。

@XmlAccessorType(XmlAccessType.FIELD)

@XmlType(name = "", propOrder = {"sender","sheet" })

@XmlRootElement(name = "AUTO ")

 

public class DataFile{

 

    @XmlElement(name="Sender",required = true)

    protected Sender sender;

   

    public Sender getSender() {

       return sender;

    }

    public void setSender(Sender sender) {

       this.sender = sender;

    }

 

现在遇到个问题,就是@XmlRootElement(name = "AUTO ")这个节点是动态的。但是注解在运行期间是改变不了得。那只有改字节码了。Asm?cglib? javassist?..等等修改字节码的库。比较方便的还是cglibjavassist吧。因为它们都是对Asm的封装。

/**

 * 运行时动态修改注解值

 * @author c_zhangzengmin002

 *

 */

public class ClassUtils {

 

    //缓存加载器加载的calss对象

    private static final Map<String, Class<?>> classPoolMap=new ConcurrentHashMap<String, Class<?>>();

   

    private ClassUtils(){}

   

    /**

     * 运行时动态修改注解值

     * @param Class

     *

     * @param entityClassName

     *            待映射的实体全限定类名

     * @param  annotation 需要修改的注解全限定类名

     * @param annotationAttrName 注解属性名称

     * @param annotationVal 注解属性值

     *           

     * @return 映射后的类对象

     */

    public static  Class<?> updateAnnotationForClass(String entityClassName,String annotationClassName, String annotationAttrName,String annotationVal)throws Exception {

       Class<?> c = null;

       if(StringUtil.isBlank(entityClassName) || StringUtil.isBlank(annotationClassName)

              || StringUtil.isBlank(annotationAttrName) || StringUtil.isBlank(annotationVal)){

           return c;

       }

       c=classPoolMap.get(annotationVal);

       if(null!=c){

           return c;

       }

       try {

           ClassPool classPool = ClassPool.getDefault();

           classPool.appendClassPath(new ClassClassPath(ClassUtils.class));

           //classPool.importPackage("javax.persistence");

           CtClass clazz = classPool.get(entityClassName);

           clazz.defrost();

           ClassFile classFile = clazz.getClassFile();

             

           ConstPool constPool = classFile.getConstPool();

           Annotation tableAnnotation = new Annotation(

                  annotationClassName, constPool);

           tableAnnotation.addMemberValue(annotationAttrName, new StringMemberValue(

                  annotationVal, constPool));

           // 获取运行时注解属性

           AnnotationsAttribute attribute = (AnnotationsAttribute) classFile

                  .getAttribute(AnnotationsAttribute.visibleTag);

           attribute.addAnnotation(tableAnnotation);

           classFile.addAttribute(attribute);

           classFile.setVersionToJava5();

           // clazz.writeFile();

            

           AnnotationClassLoader loader = new AnnotationClassLoader(

                  ClassUtils.class.getClassLoader());

//加载器加载class文件,一个加载器只会加载一次路径名称相同的calss

//这里因为只改了注解,类路径是没有改变的。

           c = clazz.toClass(loader, null);

           if(null!=c){

              classPoolMap.put(annotationVal, c);

           }

       } catch (Exception e) {

           e.printStackTrace();

       }

       return c;

    }

 

    public static void main(String[] args)throws Exception {       Class<?> clazz3 = ClassUtils.updateAnnotationForClass(

    "com.dep.jaxb.DataFile","javax.xml.bind.annotation.XmlRootElement","name", "AUTO_IDS");

       System.out.println("修改后的@XmlRootElement: " + clazz3.getAnnotation(XmlRootElement.class).name());

    }

}

 

/**

     * <p>

     * Description:根据class类型,将文件流转换成对象。在这个过程中会对文件进行编码处理

     * </p>

     * <p>

     * Create Time:2012-9-31

     * </p>

     *

     * @author zzm

     * @param Class

     *            <?>

     * @param BufferedReader

     *            文件流

     * @throws Exception

     */

    public static Object unmarshalClaim(Class<?> c, BufferedReader in)

           throws Exception {

       StringBuilder buffer = null;

       JAXBContext jaxbContext;

       try {

          

           buffer = new StringBuilder();

           String line = "";

           if (in != null) {

              while ((line = in.readLine()) != null) {

                  buffer.append(line);

              }

 

           }

          

           //所取头结点名称

           String dataFileName=StringUtil.getXMlHandleNodeString(buffer);

           //获取动态class对象

           Class<?> calss=ClassUtils.updateAnnotationForClass(Constant.DATAFILE_CLASS_NAME, Constant.XMLROOTELEMENT_CLASS_NAME,

                  Constant.NAME_STR, dataFileName);

           if(null!=calss){

              c=calss;

           }

           String xmlString = StringUtil.getXMlString(buffer);

          

           StreamSource streamSource = new StreamSource(new StringReader(

                  xmlString));

          

           // 加载映射bean

           jaxbContext = JAXBContext.newInstance(c);

           // 创建解析

           Unmarshaller um = jaxbContext.createUnmarshaller();

           return unmarshalClaim(um,streamSource);

       } catch (Exception e) {

           log.error(e);

           e.printStackTrace();

           throw new BasicException(e.getMessage());

       }finally{

           in.close();

       }

    }

 

问题来了!

public static void unmarshalClaim()throws Exception {

       String s = "E:\\Documents and Settings\\c_zhangzengmin002\\桌面\\xml\\1.xml";

       //xml动态的转换成相应的javaBean对象

       Object obj = JAXBUtil.unmarshalClaim(DataFile.class, s);

        //这样问题来了,这里强转报错了。因为要动态获取的class对象。这里是使用不同的加载器加载的calss对象实例。不同加载器加载的对象实例是不一样的。

       //DataFile newStudent = (DataFile) obj

    }

不同加载器加载同class对象实例是不一样的。当一个类实例化时,首先会对其父类实例化。

解决:

@XmlAccessorType(XmlAccessType.FIELD)

@XmlType(name = "", propOrder = {"sender","sheet" })

@XmlRootElement(name = "AUTO ")

public class DataFile extends AbstractDataFile{

 

    @XmlElement(name="Sender",required = true)

    protected Sender sender;

   

    public Sender getSender() {

       return sender;

    }

    public void setSender(Sender sender) {

       this.sender = sender;

    }

public abstract class AbstractDataFile {

 

    public Sender getSender() {return null;};

}

 

    public static void unmarshalClaim()throws Exception {

       String s = "E:\\Documents and Settings\\c_zhangzengmin002\\桌面\\xml\\1.xml";

        //自定义加载器加载的对象

       Object newStudent2 = JAXBUtil.unmarshalClaim(DataFile.class, s3);

       //默认加载器加载的对象

       DataFile dataFile =new DataFile();

       AbstractDataFile newStudent = (AbstractDataFile) newStudent2;

 

       System.out.println(dataFile.getClass().getClassLoader());

       System.out.println(newStudent.getClass().getClassLoader());

    //父类的加载器  System.out.println(dataFile.getClass().getSuperclass().getClassLoader());

    //父类的加载器  System.out.println(newStudent.getClass().getSuperclass().getClassLoader());

 

    }

运行结果:

sun.misc.Launcher$AppClassLoader@82ba41

com.dep.util.EntityClassLoader@a39137

sun.misc.Launcher$AppClassLoader@82ba41

sun.misc.Launcher$AppClassLoader@82ba41

结果发现,父类都是由同一加载器加载的。目前解决此问题就想到这个办。应该还有其他的方法。

1
3
分享到:
评论
1 楼 xinglianxlxl 2018-03-28  
以后看看,谢谢

相关推荐

    JAXB-XML注解-应用

    JAXB-XML注解-应用

    jaxb-api jaxb-impl jaxb-xjc jaxws-rt jar包

    jaxb-api jaxb-impl jaxb-xjc jaxws-rt 这四个文件对应的jar包

    jaxb-core-2.2.10-b140310.1920-API文档-中文版.zip

    赠送jar包:jaxb-core-2.2.10-b140310.1920.jar; 赠送原API文档:jaxb-core-2.2.10-b140310.1920-javadoc.jar; 赠送源代码:jaxb-core-2.2.10-b140310.1920-sources.jar; 赠送Maven依赖信息文件:jaxb-core-...

    jackson-module-jaxb-annotations-2.2.3-API文档-中文版.zip

    赠送jar包:jackson-module-jaxb-annotations-2.2.3.jar; 赠送原API文档:jackson-module-jaxb-annotations-2.2.3-javadoc.jar; 赠送源代码:jackson-module-jaxb-annotations-2.2.3-sources.jar; 赠送Maven依赖...

    jaxb-svg11-1.0.2-API文档-中英对照版.zip

    赠送jar包:jaxb-svg11-1.0.2.jar; 赠送原API文档:jaxb-svg11-1.0.2-javadoc.jar; 赠送源代码:jaxb-svg11-1.0.2-sources.jar; 赠送Maven依赖信息文件:jaxb-svg11-1.0.2.pom; 包含翻译后的API文档:jaxb-svg11...

    jaxb-svg11-1.0.2-API文档-中文版.zip

    赠送jar包:jaxb-svg11-1.0.2.jar; 赠送原API文档:jaxb-svg11-1.0.2-javadoc.jar; 赠送源代码:jaxb-svg11-1.0.2-sources.jar; 赠送Maven依赖信息文件:jaxb-svg11-1.0.2.pom; 包含翻译后的API文档:jaxb-svg11...

    jackson-module-jaxb-annotations-2.7.8-API文档-中英对照版.zip

    赠送jar包:jackson-module-jaxb-annotations-2.7.8.jar; 赠送原API文档:jackson-module-jaxb-annotations-2.7.8-javadoc.jar; 赠送源代码:jackson-module-jaxb-annotations-2.7.8-sources.jar; 赠送Maven依赖...

    maven-jaxb2-plugin-0.14.0.jar

    JAXB能够使用Jackson对JAXB注解的支持实现(jackson-module-jaxb-annotations),既方便生成XML,也方便生成JSON,这样一来可以更好的标志可以转换为JSON对象的JAVA类。JAXB允许JAVA人员将JAVA类映射为XML表示方式,...

    jaxb-api jaxb-impl jar

    jaxb-api jaxb-impl jar

    jaxb-api-2.3.1-API文档-中英对照版.zip

    赠送jar包:jaxb-api-2.3.1.jar; 赠送原API文档:jaxb-api-2.3.1-javadoc.jar; 赠送源代码:jaxb-api-2.3.1-sources.jar; 包含翻译后的API文档:jaxb-api-2.3.1-javadoc-API文档-中文(简体)-英语-对照版.zip ...

    jaxb-runtime-2.3.5-API文档-中文版.zip

    赠送jar包:jaxb-runtime-2.3.5.jar; 赠送原API文档:jaxb-runtime-2.3.5-javadoc.jar; 赠送源代码:jaxb-runtime-2.3.5-sources.jar; 赠送Maven依赖信息文件:jaxb-runtime-2.3.5.pom; 包含翻译后的API文档:...

    jaxb-runtime-2.3.5-API文档-中英对照版.zip

    赠送jar包:jaxb-runtime-2.3.5.jar; 赠送原API文档:jaxb-runtime-2.3.5-javadoc.jar; 赠送源代码:jaxb-runtime-2.3.5-sources.jar; 赠送Maven依赖信息文件:jaxb-runtime-2.3.5.pom; 包含翻译后的API文档:...

    jaxb-impl-2.2.10-b140310.1920-API文档-中文版.zip

    赠送jar包:jaxb-impl-2.2.10-b140310.1920.jar; 赠送原API文档:jaxb-impl-2.2.10-b140310.1920-javadoc.jar; 赠送源代码:jaxb-impl-2.2.10-b140310.1920-sources.jar; 赠送Maven依赖信息文件:jaxb-impl-...

    jaxb-api-2.3.0-API文档-中文版.zip

    赠送jar包:jaxb-api-2.3.0.jar; 赠送原API文档:jaxb-api-2.3.0-javadoc.jar; 赠送源代码:jaxb-api-2.3.0-sources.jar; 赠送Maven依赖信息文件:jaxb-api-2.3.0.pom; 包含翻译后的API文档:jaxb-api-2.3.0-...

    javax.rar(jaxb-impl-2.3.0、jaxb-core-2.3.0、jaxb-api-2.3.0)

    有关Maven项目中缺少jaxb-api的异常报错解决,jaxb-api-2.3.0.jar

    jaxb-api-2.3.0-API文档-中英对照版.zip

    赠送jar包:jaxb-api-2.3.0.jar; 赠送原API文档:jaxb-api-2.3.0-javadoc.jar; 赠送源代码:jaxb-api-2.3.0-sources.jar; 赠送Maven依赖信息文件:jaxb-api-2.3.0.pom; 包含翻译后的API文档:jaxb-api-2.3.0-...

    jackson-module-jaxb-annotations-2.7.8-API文档-中文版.zip

    赠送jar包:jackson-module-jaxb-annotations-2.7.8.jar; 赠送原API文档:jackson-module-jaxb-annotations-2.7.8-javadoc.jar; 赠送源代码:jackson-module-jaxb-annotations-2.7.8-sources.jar; 赠送Maven依赖...

    jaxb-api-2.0.jar

    jaxb-api-2.0.jar jaxb-api-2.0.jar

    jaxb-api-2.2.2-API文档-中文版.zip

    赠送jar包:jaxb-api-2.2.2.jar; 赠送原API文档:jaxb-api-2.2.2-javadoc.jar; 赠送源代码:jaxb-api-2.2.2-sources.jar; 赠送Maven依赖信息文件:jaxb-api-2.2.2.pom; 包含翻译后的API文档:jaxb-api-2.2.2-...

    jaxb-api-2.2.11-API文档-中英对照版.zip

    赠送jar包:jaxb-api-2.2.11.jar; 赠送原API文档:jaxb-api-2.2.11-javadoc.jar; 赠送源代码:jaxb-api-2.2.11-sources.jar; 赠送Maven依赖信息文件:jaxb-api-2.2.11.pom; 包含翻译后的API文档:jaxb-api-...

Global site tag (gtag.js) - Google Analytics