Get the next packet is assigned a java class annotated

Scheme 1: The reflections frame (this frame dependent com.google.guava)

        1, reflections framework Address: https://github.com/ronmamo/reflections

        2, Project Dependencies

        <dependency>
            <groupId>org.reflections</groupId>
            <artifactId>reflections</artifactId>
            <version>0.9.11</version>
        </dependency>

        <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId>
            <version>21.0</version>
        </dependency>

       3, implementation code

 // reference into the package name to be scanned
 Reflections f = new Reflections("com.ggband.netty.execute.command");
 // into the reference target class notes
 Set<Class<?>> set = f.getTypesAnnotatedWith(Cmd.class);

 

Option II: The scanning ClassLoader

     1, implementation code

package com.ggband.netty;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class Scanner {
    /**
     * Get all the packages from the package in Class
     *
     * @param packageName
     * @return
     */
    public Set<Class<?>> getClasses(String packageName) throws Exception {

        // set of first class category
         // List <Class <>> classes = new new ArrayList <Class <>> ();?? 
        The Set <Class <= >> classes? New new HashSet <> ();
         // if loop iterations 
        Boolean recursive this = to true ;
         // Get the name of the package and the replacement 
        String packageDirName packageName.replace = (, '/' '.' );
         // definition of an enumerated set of things and loop to handle this directory 
        the Enumeration <the URL> dirs;
         the try {
            dirs = Thread.currentThread () getContextClassLoader () getResources (packageDirName);..
             // iteration of the loop continues 
            the while (dirs.hasMoreElements ()) {
                 // get the next element of 
                the URL URL = dirs.nextElement ();
                 // get agreement name 
                String Protocol = url.getProtocol ();
                 // if the form of files stored on the server 
                IF ( "file" .equals (Protocol)) {
                     // get the package physical path 
                    String filePath = URLDecoder.decode (url .getFile (), "UTF-. 8" );
                     //Scan files as files in the entire package, and added to the collection 
                    addClass (classes, filePath, packageName) ;
                } The else  IF ( "jar" .equals (Protocol)) {
                     // if jar package file
                     // define a JarFile to 
                    JarFile to jar;
                     the try {
                         // Get jar 
                        jar = . ((JarURLConnection to) url.openConnection ()) getJarFile ( );
                         // from this package to obtain an enumeration class jar 
                        the enumeration <the JarEntry for> = entries It jar.entries ();
                         // same loop iterations performed 
                        the while (entries.hasMoreElements ()) {
                             //An entity acquired in the jar can be a directory and some other jar file META-INF bag as other documents 
                            the JarEntry for the entry = entries.nextElement ();
                            Name String = entry.getName ();
                             // if by starting with / 
                            IF (name.charAt (0) == '/' ) {
                                 // Get string behind 
                                name name.substring = (. 1 );
                            }
                            // if the package name and the same as defined in the first part 
                            IF (name.startsWith (packageDirName)) {
                                 int IDX = name.lastIndexOf ( '/' );
                                 // if the ending "/" is a packet 
                                IF ! (IDX = - 1 ) {
                                     // Get the package name "/" replace "." 
                                    the packageName name.substring = (0, IDX) .replace ( '/', '.' );
                                }
                                // If you can go on and iteration is a package 
                                IF ((IDX! = -1) || recursive This) {
                                     // If it is not a .class file and directory 
                                    IF (name.endsWith (. "Class") &&! Entry. the isDirectory ()) {
                                         // remove behind ".class" Get real class name 
                                        String className = name.substring (packageName.length () +. 1, name.length () -. 6 );
                                         the try {
                                             // Add to classes 
                                            classes.add (the Class.forName (the packageName + + '.' className));
                                        } catch (ClassNotFoundException e) {
                                            e.printStackTrace ();
                                        }
                                    }
                                }
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace ();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace ();
        }

        return classes;
    }

    public void addClass(Set<Class<?>> classes, String filePath, String packageName) throws Exception {
        File[] files = new File(filePath).listFiles(file -> (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory());
        assert files != null;
        for (File file : files) {
            String fileName = file.getName();
            if (file.isFile()) {
                String classsName = fileName.substring(0, fileName.lastIndexOf("."));
                if (!packageName.isEmpty()) {
                    classsName = packageName + "." + classsName;
                }
                doAddClass(classes, classsName);
            }

        }
    }

    public void doAddClass(Set<Class<?>> classes, final String classsName) throws Exception {
        ClassLoader classLoader = new ClassLoader() {
            @Override
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                return super.loadClass(name);
            }
        };
        classes.add(classLoader.loadClass(classsName));
    }


    public <A extends Annotation> Set<Class<?>> getAnnotationClasses(String packageName, Class<A> annotationClass) throws Exception {

        // find annotated classes with the annotationClass 
        the Set <Class <= >> the Controllers? New new HashSet <> ();
        Set<Class<?>> clsList = getClasses(packageName);
        if (clsList != null && clsList.size() > 0) {
            for (Class<?> cls : clsList) {
                if (cls.getAnnotation(annotationClass) != null) {
                    controllers.add(cls);
                }
            }
        }
        return controllers;
    }


}

  2, use:

  Set<Class<?>> set = new Scanner().getAnnotationClasses("com.ggband.netty.execute.command", Cmd.class);

Expansion: You can now implement your own business, and such scan com.ggband.netty.execute.command coated Cmd annotated classes to get an instance Cmd notes and annotated value classes

 Map<String, Command> beanContainer = new HashMap<>();
try {
//@1 采用reflections 框架(此框架依赖com.google.guava)
// Reflections f = new Reflections("com.ggband.netty.execute.command");
// Set<Class<?>> set = f.getTypesAnnotatedWith(Cmd.class);
//@2 采用ClassLoader扫描
Set<Class<?>> set = new Scanner().getAnnotationClasses("com.ggband.netty.execute.command", Cmd.class);
for (Class<?> c : set) {
Object bean = c.newInstance();
Cmd annotation = c.getAnnotation(Cmd.class);
beanContainer.put(Arrays.toString(annotation.value()), (Command) bean);
}
} catch (Exception e) {
e.printStackTrace();
}

 

Guess you like

Origin www.cnblogs.com/ggband/p/11668879.html