<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    走自己的路

    路漫漫其修遠兮,吾將上下而求索

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      50 隨筆 :: 4 文章 :: 118 評論 :: 0 Trackbacks
    Asm是很好的ByteCode generator 和 ByteCode reader。Asm提供了ClassVisitor來訪問Class中的每個元素。當用ClassReader來讀取Class的字節碼時,每read一個元素,ASM會調用指定的ClassVisitor來訪問這個元素。這就是訪問者模式。利用這個特點,當ClassVisitor訪問Class的Annotation元素時,我們會把annotation的信息記錄下來。這樣就可以在將來使用這個Annotation。
    舉一個例子吧,我們用AnnotationFaker來標注一個Class,也就是Annotation的target是Type級別。當我們發現某個class是用AnnotationFaker標注的,我們就load這個class到jvm中,并初始化,否則免談。

    1.AnnotationFaker: annnotation用來標注需要初始化的class
     1package com.oocl.isdc.sha.frm.test.config;
     2
     3import java.lang.annotation.ElementType;
     4import java.lang.annotation.Retention;
     5import java.lang.annotation.RetentionPolicy;
     6import java.lang.annotation.Target;
     7
     8@Retention(RetentionPolicy.RUNTIME)
     9@Target({ElementType.TYPE})
    10public @interface AnnotationFaker {
    11}

    12

    2.ClassFaker: 被AnnotationFaker標注的class

    1package com.oocl.isdc.sha.frm.test.config;
    2
    3@AnnotationFaker
    4public class ClassFaker {
    5    public void hello() {
    6        System.out.println("hello world, load me success!");
    7    }

    8}

    9


    3.ClassVisitorFaker:ClassVisitor的一個實現,用來得到class上的Annotation

     1package com.oocl.isdc.sha.frm.test.config;
     2
     3import java.util.ArrayList;
     4import java.util.List;
     5
     6import org.objectweb.asm.AnnotationVisitor;
     7import org.objectweb.asm.Attribute;
     8import org.objectweb.asm.ClassVisitor;
     9import org.objectweb.asm.FieldVisitor;
    10import org.objectweb.asm.MethodVisitor;
    11import org.objectweb.asm.tree.AnnotationNode;
    12
    13public class ClassVisitorFaker implements ClassVisitor{
    14
    15    public List<AnnotationNode> visibleAnnotations;
    16
    17    public List<AnnotationNode> invisibleAnnotations;
    18    
    19    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
    20      
    21    }

    22
    23    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
    24        AnnotationNode an = new AnnotationNode(desc);
    25        if (visible) {
    26            if (visibleAnnotations == null{
    27                visibleAnnotations = new ArrayList<AnnotationNode> (1);
    28            }

    29            visibleAnnotations.add(an);
    30        }
     else {
    31            if (invisibleAnnotations == null{
    32                invisibleAnnotations = new ArrayList<AnnotationNode> (1);
    33            }

    34            invisibleAnnotations.add(an);
    35        }

    36        return an;
    37    }

    38
    39    public void visitAttribute(Attribute attr) {
    40    }

    41
    42    public void visitEnd() {
    43    }

    44
    45    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
    46        return null;
    47    }

    48
    49    public void visitInnerClass(String name, String outerName, String innerName, int access) {
    50    }

    51
    52    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    53        return null;
    54    }

    55
    56    public void visitOuterClass(String owner, String name, String desc) {
    57    }

    58
    59    public void visitSource(String source, String debug) {
    60    }

    61
    62    public List<AnnotationNode> getVisibleAnnotations() {
    63        return visibleAnnotations;
    64    }

    65
    66    public List<AnnotationNode> getInvisibleAnnotations() {
    67        return invisibleAnnotations;
    68    }

    69}

    70


    4.ClassParser: main class, 分析classpath上的class,如果是用AnnotationFaker標注的class,我們就初始化它。

      1package com.oocl.isdc.sha.frm.test.config;
      2
      3import java.io.File;
      4import java.io.IOException;
      5import java.net.URISyntaxException;
      6import java.net.URL;
      7import java.net.URLClassLoader;
      8import java.net.URLDecoder;
      9import java.util.Enumeration;
     10import java.util.HashSet;
     11import java.util.Iterator;
     12import java.util.List;
     13import java.util.Set;
     14import java.util.zip.ZipEntry;
     15import java.util.zip.ZipException;
     16import java.util.zip.ZipFile;
     17
     18import org.objectweb.asm.ClassReader;
     19import org.objectweb.asm.Type;
     20import org.objectweb.asm.tree.AnnotationNode;
     21
     22public class ClassParser {
     23    @SuppressWarnings("unchecked")
     24    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException,
     25            IllegalAccessException, URISyntaxException {
     26        Set<String> result = new HashSet<String>();
     27
     28        if (getClassLoader() instanceof URLClassLoader) {
     29            URL[] urls = ((URLClassLoader) getClassLoader()).getURLs();
     30            for (URL u : urls) {
     31                File file = new File(u.toURI());
     32                if (file.isDirectory()) {
     33                    handleDirectory(result, file, null);
     34                }
     else if (file.getName().toLowerCase().endsWith(".jar")) {
     35                    handleArchive(result, file);
     36                }

     37            }

     38        }
    else{
     39            Enumeration<URL> urls = getClassLoader().getResources(".");
     40            while (urls.hasMoreElements()) {
     41                String urlPath = urls.nextElement().getFile();
     42                // System.out.println(urlPath);
     43                urlPath = URLDecoder.decode(urlPath, "UTF-8");
     44                if (urlPath.startsWith("file:")) {
     45                    urlPath = urlPath.substring(5);
     46                }

     47                if (urlPath.indexOf('!'> 0{
     48                    urlPath = urlPath.substring(0, urlPath.indexOf('!'));
     49                }

     50
     51                final File file = new File(urlPath);
     52                if (file.isDirectory()) {
     53                    handleDirectory(result, file, null);
     54                }

     55
     56            }

     57        }

     58
     59     
     60
     61        for (String clsRsName : result) {
     62            ClassVisitorFaker cv = new ClassVisitorFaker();
     63            ClassReader cr = new ClassReader(getClassLoader().getResourceAsStream(clsRsName));
     64            cr.accept(cv, 0);
     65            List<AnnotationNode> annotationsList = cv.getVisibleAnnotations();
     66            if (null != annotationsList) {
     67                for (Iterator<AnnotationNode> it = annotationsList.iterator(); it.hasNext();) {
     68                    AnnotationNode annotation = it.next();
     69                    Type t = Type.getType(annotation.desc);
     70                    if (AnnotationFaker.class.getName().equals(t.getClassName())) {
     71                        Class clazz = Class.forName(filenameToClassname(clsRsName));
     72                        ClassFaker faker = (ClassFaker) clazz.newInstance();
     73                        faker.hello();
     74                    }

     75                }

     76            }

     77
     78        }

     79
     80    }

     81
     82    private static void handleDirectory(final Set<String> result, final File file, final String path)
     83            throws ZipException, IOException {
     84        for (final File child : file.listFiles()) {
     85            final String newPath = path == null ? child.getName() : path + '/' + child.getName();
     86            if (child.isDirectory()) {
     87                handleDirectory(result, child, newPath);
     88            }
     else if (child.getName().toLowerCase().endsWith(".jar")) {
     89                handleArchive(result, child);
     90            }
     else {
     91                handleItem(result, newPath);
     92            }

     93        }

     94    }

     95
     96    private static void handleItem(final Set<String> result, final String name) {
     97        if (name.endsWith(".class")) {
     98            result.add(name);
     99        }

    100    }

    101
    102    private static void handleArchive(final Set<String> result, final File file) throws ZipException, IOException {
    103        final ZipFile zip = new ZipFile(file);
    104        final Enumeration<? extends ZipEntry> entries = zip.entries();
    105        while (entries.hasMoreElements()) {
    106            final ZipEntry entry = entries.nextElement();
    107            final String name = entry.getName();
    108            handleItem(result, name);
    109        }

    110    }

    111
    112    private static ClassLoader getClassLoader() {
    113        ClassLoader clsLoader = Thread.currentThread().getContextClassLoader();
    114        if (clsLoader == null{
    115            clsLoader = ClassLoader.getSystemClassLoader();
    116        }

    117        return clsLoader;
    118    }

    119
    120    public static String filenameToClassname(final String filename) {
    121        return filename.substring(0, filename.lastIndexOf(".class")).replace('/''.').replace('\\''.');
    122    }

    123
    124}

    125


    posted on 2008-06-11 17:38 叱咤紅人 閱讀(2939) 評論(0)  編輯  收藏 所屬分類: J2SE and JVM 、Other Java and J2EE frameworks
    主站蜘蛛池模板: 亚洲国产成人一区二区精品区| 人妖系列免费网站观看| 国产亚洲成AV人片在线观黄桃 | 久久久久亚洲AV片无码| 国产成人免费全部网站| 日韩欧毛片免费视频| 久久精品免费一区二区三区| 日本一区二区在线免费观看| 国产精品亚洲专区在线观看| 亚洲AV日韩精品久久久久久久| 国产精品亚洲综合一区| 国产男女猛烈无遮挡免费视频网站 | 亚洲福利视频一区| 国产AV无码专区亚洲AV手机麻豆| 老司机永久免费网站在线观看| 国产成人免费网站| **一级毛片免费完整视| 国产成人免费ā片在线观看老同学| 国产一区二区三区亚洲综合| 亚洲中文字幕无码中文| 一级**爱片免费视频| 亚洲av综合日韩| 亚洲欧美在线x视频| 亚洲AV综合永久无码精品天堂| 亚洲 日韩 色 图网站| 亚洲综合成人婷婷五月网址| 亚洲人成网站在线观看播放动漫| 在线观看亚洲一区二区| 78成人精品电影在线播放日韩精品电影一区亚洲 | 日韩精品免费一线在线观看| 国产亚洲蜜芽精品久久| 精品国产亚洲AV麻豆| 激情无码亚洲一区二区三区| 亚洲av永久中文无码精品 | 免费人成在线观看网站视频| 国产一级淫片a视频免费观看| 日本免费福利视频| 免费吃奶摸下激烈视频| 亚洲成网777777国产精品| EEUSS影院WWW在线观看免费| sihu国产精品永久免费|