Scan classes with specified annotation under specified package

Scan classes with specified annotation under specified package.

 

steps:

* define annotation

* use annotation on class

* get class set with specified annotations under specified packages,

      2 approach:

      * spring (preferred)

            use util class from spring:

                  ClassPathScanningCandidateComponentProvider

      * reflections lib

            this lib provide class/methods to do this,

            but it's not as good as spring,

      * 

* iterate the class set, read annotation, take actions as need,

 

maven:

		
		
			org.springframework
			spring-context
			4.0.2.RELEASE
		
		
			org.reflections
			reflections
			0.9.9-RC1
		
		
			junit
			junit
			4.8.2
		
		
			log4j
			log4j
			1.2.16
		

 

 

Util class:

package eric.j2se.anno;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;

import org.reflections.Reflections;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;

/**
 * Util to get classes according to annotation on class in a specified package.
 * 
 * @author eric
 * @date Aug 5, 2014 12:36:42 PM
 */
public class PkgAnnoUtil {
	/**
	 * 
	 * 

* Scan class with specified annotation under specific packages, using util from spring. *

*

* Sub package & inner class will be included. *

* * @param pkgArray * an array of package path, * @param annoClazzArray * an array of annotation class, * @return */ public static Set getBeanSetWithAnno(String pkgArray[], Class[] annoClazzArray) { // prepare scanner, with each annotation, ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(true); for (Class annoclazz : annoClazzArray) { scanner.addIncludeFilter(new AnnotationTypeFilter(annoclazz)); } Set beanSet = null; // search with each package, and combine search result, for (String pkg : pkgArray) { if (beanSet == null) { beanSet = scanner.findCandidateComponents(pkg); } else { beanSet.addAll(scanner.findCandidateComponents(pkg)); } } return beanSet; } /** *

* Scan class with specified annotation under a specific package, using a lib called "reflections". *

*

* Sub package & inner class will be included. *

*

* This method is deprecated, use getBeanSetWithAnno() instead. *

* * @param pkg * package path * @param annoClazz * annotation class * @return a set of class, or null if error occur, */ @Deprecated public static Set> getClazzSetWithAnno(String pkg, Class annoClazz) { // get class set Set> clazzSet = new Reflections(pkg).getTypesAnnotatedWith(annoClazz); // get class set that with a specific annotation Set> clazzWithAnnoSet = new HashSet>(); for (Class clazz : clazzSet) { if (clazz.getAnnotation(annoClazz) != null) { clazzWithAnnoSet.add(clazz); } } return clazzWithAnnoSet; } }

 

junit test:

package eric.j2se.anno;

import java.lang.reflect.Method;
import java.util.Set;

import junit.framework.TestCase;

import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;

public class PkgAnnoUtilTest extends TestCase {
	private Class annoClazz = SimpleAnno.class; // annotation to filter class,
	private String pkg = "eric.j2se.anno.annopkg"; // package name to be search,
	private String methodName = "takeAction"; // name of method to execute,

	private int annotatedClassCount = 4; // count of class that is annotated,

	/**
	 * test - getBeanSetWithAnno(),
	 */
	@Test
	@SuppressWarnings("unchecked")
	public void testGetBeanSetWithAnno() {
		System.out.println("------ annotation scan - spring - start ------");
		// get classes with in package, and has specified annotation,
		Set beanWithAnnoSet = PkgAnnoUtil.getBeanSetWithAnno(new String[] { pkg }, new Class[] { annoClazz });
		assertEquals(beanWithAnnoSet.size(), annotatedClassCount);

		try {
			// execute a specific method,
			for (BeanDefinition bean : beanWithAnnoSet) {
				Class clazz = Class.forName(bean.getBeanClassName());
				Method md = clazz.getMethod(methodName);
				if (md != null) {
					md.invoke(clazz.newInstance());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println("------ annotation scan - spring - end ------\n");
	}

	/**
	 * test - getClazzSetWithAnnoTest(),
	 */
	@SuppressWarnings("deprecation")
	@Test
	public void testGetClazzSetWithAnno() {
		System.out.println("------ annotation scan - reflections lib - start ------");
		// get classes with in package, and has specified annotation,
		Set> clazzWithAnnoSet = PkgAnnoUtil.getClazzSetWithAnno(pkg, annoClazz);
		assertEquals(clazzWithAnnoSet.size(), annotatedClassCount);

		try {
			// execute a specific method,
			for (Class clazz : clazzWithAnnoSet) {
				Method md = clazz.getMethod(methodName);
				if (md != null) {
					md.invoke(clazz.newInstance());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println("------ annotation scan - reflections lib - end ------\n");
	}
}

 

你可能感兴趣的:(J2SE)