javassist----动态修改注解

1、为什么要动态修改注解?

@Table(name = "pay_flow")
public class PayFlowDB {
    @Id(insertable = true)
    @Column(name = "id")
    private Long    id;
为了方便进行数据库操作和转换,在实体中加入注解来标示table_name和对应的field_name。通过注解大大减少了dao层的代码量。具体实体如上。

同时问题也来了?

分表的数据结构

由于数据库层面进行分表,导致table_name会不一样,但是对应的其他属性和字段都是一样的。如果如下进行手动添加对应的实体,很明显是无法接受的。

@Table(name = "pay_flow1")
public class PayFlowDB1 {
    @Id(insertable = true)
    @Column(name = "id")
    private Long    id;
@Table(name = "pay_flow2")
public class PayFlowDB2 {
    @Id(insertable = true)
    @Column(name = "id")
    private Long    id;

这个时候就需要动态修改注解的name属性

2、怎样利用jdk已有的api进行动态修改?

具体见如下代码

// 动态修改注解部分代码 

// 从实现的角度说,ClassPool是一个CtClass对象的hash表,类名做为key。ClassPool的get()搜索hash表找到与指定key关联的CtClass对象。
ClassPool classPool = ClassPool.getDefault();
classPool.appendClassPath(new ClassClassPath(ClassPoolUtils.class));
// 如果CtClass通过writeFile(),toClass(),toBytecode()转换了类文件,javassist冻结了CtClass对象。
// 以后是不允许修改这个 CtClass对象。这是为了警告开发人员当他们试图修改一个类文件时,已经被JVM载入的类不允许被重新载入。
CtClass clazz = classPool.get(entityClassName);
clazz.stopPruning(true);
// Defrost()执行后,CtClass对象将可以再次修改。
clazz.defrost();
ClassFile classFile = clazz.getClassFile();

ConstPool constPool = classFile.getConstPool();
Annotation tableAnnotation = new Annotation(annotationName, constPool);
tableAnnotation.addMemberValue("name", new StringMemberValue(tableName, constPool));
// 获取运行时注解属性  
AnnotationsAttribute attribute = (AnnotationsAttribute) classFile.getAttribute(AnnotationsAttribute.visibleTag);
attribute.addAnnotation(tableAnnotation);
classFile.addAttribute(attribute);
classFile.setVersionToJava5();
// 当前ClassLoader中必须尚未加载该实体。(同一个ClassLoader加载同一个类只会加载一次)
EntityClassLoader loader = new EntityClassLoader(ClassPoolUtils.class.getClassLoader());
c = clazz.toClass(loader, null);


//该加载器主要用于运行时动态修改实体后,重新装载实体 

public class EntityClassLoader extends ClassLoader {

    private ClassLoader parent;

    EntityClassLoader(ClassLoader parent) {
        this.parent = parent;
    }

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return this.loadClass(name, false);
    }

    @Override
    protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        Class<?> clazz = this.findLoadedClass(name);
        if (null != parent)
            clazz = parent.loadClass(name);
        if (null == clazz)
            this.findSystemClass(name);
        if (null == clazz)
            throw new ClassNotFoundException();
        if (resolve)
            this.resolveClass(clazz);
        return clazz;
    }
}

你可能感兴趣的:(javassist,java注解)