`
lushuaiyin
  • 浏览: 674998 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java注解研究实例

 
阅读更多

注解(Annotation) 为我们在代码中天界信息提供了一种形式化的方法,是我们可以在稍后

某个时刻方便地使用这些数据(通过 解析注解 来使用这些数据)。

现在我们开始研究怎么使用自定义注解,从而了解注解是怎么工作的。

定义一个注解 MyAnnotationClassDefinition.java

package org.lsy.test.little;

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

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotationClassDefinition {
	
	public String classExplanation();
	public String classEessage();
	
	
	//也可以给一个默认值,如下
	//public String classExplanation() default "";
}

要注意的是注解定义的形式是@interface,它本身也需要注解,而且是不可缺少的。

其中主要的2个是:@Target , @Retention

作用是;

@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括:
ElemenetType.CONSTRUCTOR 构造器声明
ElemenetType.FIELD 域声明(包括 enum 实例)
ElemenetType.LOCAL_VARIABLE 局部变量声明
ElemenetType.METHOD 方法声明
ElemenetType.PACKAGE 包声明
ElemenetType.PARAMETER 参数声明
ElemenetType.TYPE 类,接口(包括注解类型)或enum声明

@Retention 表示在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括:
RetentionPolicy.SOURCE 注解将被编译器丢弃
RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃
RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。

还有

@Documented 将此注解包含在 javadoc 中

@Inherited 允许子类继承父类中的注解

上面的注解只能用在类上面,

我们再定义一个可以用在方法上的。

MyAnnotationDefinition,java

package org.lsy.test.little;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotationDefinition {
	
	public String explanation();
	public String message();
}


写一个很普通的类:OneClass.java

注意,要使用注解

package org.lsy.test.little;

@MyAnnotationClassDefinition(classExplanation="我是类OneClass的classExplanation",classEessage="我是类OneClass的classEessage")
public class OneClass {
	
	@MyAnnotationDefinition(explanation="我是方法printMyMessageOne的explanation",
			message="我是方法printMyMessageOne的message")
	public void printMyMessageOne(){
		
	}
	
	@MyAnnotationDefinition(explanation="我是方法printMyMessageTwo的explanation",
			message="我是方法printMyMessageTwo的message")
	public void printMyMessageTwo(){
		
	}

}


再写一个main函数运行一下,看看效果

package org.lsy.test.little;

import java.lang.annotation.*;
import java.lang.reflect.Method;

public class MyAnnotationTest {

	
	public static void main(String[] args) {
		OneClass one=new OneClass();
		
		if(OneClass.class.isAnnotationPresent(MyAnnotationClassDefinition.class)){
			MyAnnotationClassDefinition myAnnotationClassDefinition=
					(MyAnnotationClassDefinition)OneClass.class.getAnnotation(MyAnnotationClassDefinition.class);
			System.out.println("类OneClass使用注解MyAnnotationClassDefinition,其属性classExplanation是:"
					+myAnnotationClassDefinition.classExplanation());
			System.out.println("类OneClass使用注解MyAnnotationClassDefinition,其属性classEessage是:"
					+myAnnotationClassDefinition.classEessage());
			
			
		}else{
			System.out.println("类OneClass没有注解MyAnnotationDefinition");
		}
		
		//
		Method[] methods = OneClass.class.getDeclaredMethods();
		for (Method method : methods) {
			 // 判断方法中是否有指定注解类型的注解
			boolean hasAnnotation = method.isAnnotationPresent(MyAnnotationDefinition.class);
			if (hasAnnotation) {
				//根据注解类型返回方法的指定类型注解
				MyAnnotationDefinition myannotation = method.getAnnotation(MyAnnotationDefinition.class);
				System.out.println("MyAnnotationDefinition( explanation = "+ 
				myannotation.explanation() + " , message = "
						+ myannotation.message() + " )");
			}
		}
	}

}


控制台打印:

类OneClass使用注解MyAnnotationClassDefinition,其属性classExplanation是:我是类OneClass的classExplanation
类OneClass使用注解MyAnnotationClassDefinition,其属性classEessage是:我是类OneClass的classEessage
MyAnnotationDefinition( explanation = 我是方法printMyMessageOne的explanation , message = 我是方法printMyMessageOne的message )
MyAnnotationDefinition( explanation = 我是方法printMyMessageTwo的explanation , message = 我是方法printMyMessageTwo的message )


由此,我们可以想到spring使用注解的原理也不外乎如此。

它先读取你的注解,然后根据读取的值去xml中寻找。

如果找到了就实例化一个对象返回。这样据实现了注入的效果。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics