`

java 自定义Annotation

    博客分类:
  • java
阅读更多

Annotation 注解,个人简单的理解就是加在方法,类,变量上的标记,即注解。通过Annotation可以筛选出你想要的类,方法,变量等。(纯个人理解,如果不对请指出! (∩_∩))。接下来就是重头戏自定义注解,自定义注解非常的方便,看代码:

 

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Name {
	String name() ;
	String desc() default "no description";
}

  这样就定义了一个名为Name的注解了,接下来看如果使用。

 

public class User {

	@Name(name="jack",desc="the great man")
	public void getName(){
		System.out.println("I'm user1");
	}
	
	@Name(name="tom",desc="the good man")
	public void getName2(){

	}
}

 

 很简单,接下来说明一下代码。在代码1中,

 第一行@Target(ElementType.METHOD), 他代表着注解的修饰范围,类型是java.lang.annotation.ElementType枚举类型。

 

public enum ElementType {  
    TYPE,//可以修饰类、接口、枚举、注解  
    FIELD,//可以修饰成员变量  
    METHOD,//可以修饰方法  
    PARAMETER,//可以修饰参数  
    CONSTRUCTOR,//可以修饰构造方法  
    LOCAL_VARIABLE,//可以修饰局部变量  
    ANNOTATION_TYPE,// 可以修饰Annotation  
    PACKAGE//可以修饰包  
}  
 

 

第二行@Retention(RetentionPolicy.RUNTIME),表示注解保留的有效期

 

//会将注解保留到编译后的class中,加载类的时候不生效  
@Retention(RetentionPolicy.CLASS)  
//仅仅在代码保留,编译后的class不会保留  
@Retention(RetentionPolicy.SOURCE)  
//在编译后的class会有,通过反射也会获得注解信息  
@Retention(RetentionPolicy.RUNTIME)  

 

 

接下来可以通过实例进一步的理解:

实例要完成的内容:假设我定义了一个名为Component的注解,然后找到指定包下含有Component注解的类并对其初始化。

首先定义Component注解

 

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
	String value();
}

 

 然后分别在User1 User2中加入Component注解

 

@Component("user1")
public class User1 {

	public void getName(){
		System.out.println("I'm user1");
	}
	
}


@Component("user2")
public class User2 {

	public void getName(){
		System.out.println("I'm user2");
	}
	
}

 

 之后可通过Java的反射机制。获取类的Annotation

 

 

public class AnnotationTest3 {

	public static void main(String[] args) {
		Map<String,Object> map = createBean("com.use",Component.class);
		User1 u1 = (User) map.get("user1");
		User2 u2= (User2) map.get("user2");
		u1.getName();
		u2.getName();
	}
	
	public static Map<String,Object> createBean(String packageName,Class<? extends Annotation> annotation) {
		
		
		List<String> classNames = getPackageAllClassName(packageName);
		Map<String,Object> map = new HashMap<String,Object>();
		try {
		for(String className : classNames){
			Class clazz;
			clazz = Class.forName(packageName +"." + className);
			
			//此处只有注解的RetentionPolicy选为RunTime,Annotation才能被取得,因为只有RunTime才被载入Jvm
			if(clazz.isAnnotationPresent(annotation)){
				Method method = annotation.getDeclaredMethod("value");
				method.setAccessible(true);//此处不是设置让此方法可以访问,而是取消了java在访问此方法时的访问检测,可以大大提高效率
				String name = (String)method.invoke(clazz.getAnnotation(annotation));
				Object o = clazz.newInstance();
				map.put(name, o);
			}
		}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return map;
	}
	
	public static List<String> getPackageAllClassName(String packageName){
		String classPath = getClassPath();
		List<String> classNames = new ArrayList<String>();
		packageName = packageName.replaceAll("[.]", "/");
		String location = classPath + packageName;
		
		File packageDir = new File(location);
		if(packageDir.isDirectory()){
			String[] fileNames = packageDir.list();
			for(String name : fileNames){
				if(name.endsWith(".class")){
					classNames.add(name.substring(0,name.indexOf(".")));
				}
			}
		}
		return classNames;
	}
	
	public static String getClassPath(){
		return AnnotationTest3.class.getResource("/").getPath();
	}
}
 

参考:http://docs.oracle.com/javase/1.5.0/docs/guide/language/annotations.html

 

http://huoyanyanyi10.iteye.com/blog/1317614

 

http://www.son1c.cn/show/859.html

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics