今天稍稍学习了下注解,关于注解,我想大家都不陌生,目前可能在hibernate配置中可能会用的多一点,在JPA中也会用到。我想说的是学习注解可以帮助我们更好的理解注解在框架中(比如hibernate和Spirng等)的应用。
Annotation是JDK5版本以来的新特性。目前在JavaSE中的学习中可能会经常遇到集合未指定泛型、使用java.util.Date类中的过时方法,编译器给出warning时,均可以采用增加注解如(SuppressWarnings("unchecked")),Deprecated等来消除警告,这样看起来会好看些。
好,下面开始进入重点学习,首先做下说明,学习Annotation时最好先了解下JDK的反射机制,关于JDK反射机制的学习,大家可以参考我之前发表的两篇博客(1. 反射初探:http://xiaoyun34286136.iteye.com/blog/190423, 2. 使用反射对类的私有方法和私有属性进行调用和修改:http://xiaoyun34286136.iteye.com/blog/1908554)。
学习Annotation涉及到的java类包含:java.lang.annotation.Annotation。所有定义的annotation均默认实现了Annotation接口,但是要注意的是,实现Annotation接口的类并不是annotation。
java中的annotation中包含的注解类型有Documented,Inherited,Retention,Target,其中常用的有Inherited(子类可以继承父类的注解),Retention(注解类型要保留多久,可否利用反射机制调用等),Target(注解的作用对象,类,接口,方法,属性等)。定义注解的关键字为@interface,关于JDK1.6自带的注解比如SuppressWarnings("unchecked")),Deprecated等我就不介绍了,相信有一定基础的都遇到过。
相信在诸如hibernate和spring等框架中,我相信这些框架是使用反射读取的注解及注解中的参数,根据这些注解和参数通过一定的逻辑来对业务进行控制的。
下面开始自定义一个注解并讲解使用,具体步骤为:
定义注解->写测试类->进行测试
一、定义注解:
注解一:AnnotationTest
@Retention(RetentionPolicy.RUNTIME) // 将Retention的值设置为RetentionPolicy.RUNTIME,这样就可以在程序运行期间可以用反射对注解进行解析,设置为CLASS何SOURCE均不能
public @interface AnnotationTest {
String value() default "good";
String value1() default "hello";
EnumTest value2(); //枚举类型
}
/**
* 自定义枚举类
*
* @author XiaoYun 2013-07-20
*/
enum EnumTest {
HELLO, world, welcome
}
注解二:
MyAnnotation.java
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* 自定义注解
*
* @author XiaoYun 2013-07-20
*/
@Retention(RetentionPolicy.CLASS)//将Retention的值设置为RetentionPolicy.CLASS,程序运行的时候就不能通过反射解析
public @interface MyAnnotation {
String value() default "hello";
String hello();
String world();
}
测试类(这里为了少写一个类,就把测试方法和类放到了一个类中):MyTest.java
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@AnnotationTest(value1="hello", value2=EnumTest.world)
@MyAnnotation(world="world", hello="hello")
public class MyTest {
@MyAnnotation(world="world", hello="hello")
private String field;
@AnnotationTest(value1="hello", value2=EnumTest.world)
@MyAnnotation(value="xiaoyun", hello="hello", world="world")
private void method() {
System.out.println("field的值为:" + field + "\nmethod from MyTest!");
}
@Override
public String toString() {
return "MyTest [field=" + field + "]";
}
/**
* 测试方法
* @param args
*/
public static void main(String[] args) throws Exception {
// 实例化对象
MyTest test = new MyTest();
// 获取Class类型
Class cls = MyTest.class;
// 根据方法名获取方法
Method method = cls.getDeclaredMethod("method", null);
// 获取属性
Field field = cls.getDeclaredField("field");
// 判断如果该方法中包含有MyAnnotation类型的注解,则进行如下操作
if (method.isAnnotationPresent(AnnotationTest.class)) {
// 取消Java访问性检查
field.setAccessible(true);
method.setAccessible(true);
// 给test对象上的field属性赋值,并执行method方法
field.set(test, "我是肖云,大家好!");
method.invoke(test, null);
// 根据注解类型获取特定的注解并打印到控制台
Annotation annotation = method.getAnnotation(AnnotationTest.class);
System.out.println(annotation.annotationType() + "\n" + annotation.annotationType().getName());
}
// 获取所有的注解并逐次迭代(这需要注解中Retention中的value为RetentionPolicy.Runntime)
Annotation[] annotations = method.getAnnotations();
if (annotations.length > 0) {
System.out.println("------------打印所有注解--------------");
for (Annotation annotation : annotations) {
System.out.println(annotation.annotationType().getCanonicalName());
}
}
}
}
上面一个例子主要说明的是java.lang.annotation.Annotation接口中的Retention属性(JVM是否保留注释,是否可用反射读取)TargetAnnotationDemo ,接下来第二个例子用到了剩下的三个属性(Documented(不是重点,生成API文档时用),Target,Inherited),下面开始介绍:
首先还是定义注解:
TargetAnnotationDemo.java
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注解
*
* @author XiaoYun 2013-07-20
*/
@Target({ElementType.TYPE, ElementType.METHOD}) //程序类型的元素有类、接口、枚举类型;方法
@Retention(RetentionPolicy.RUNTIME) //运行时可用反射调用
@Inherited //子类可以继承父类的注解
@Documented //生成doc文档时显示该注解
public @interface TargetAnnotationDemo {
String value() default "hello";
String value1();
}
第二步,写测试用例:
@TargetAnnotationDemo(value1 = "good")
public class TargetTest {
@TargetAnnotationDemo(value1 = "good")
public int add(int a, int b) {
return a + b;
}
}
/**
*子类,继承自TargetTest ,同时继承父类的TargetAnnotationDemo
*@author xiaoyun 2013-07-21
*/
class TargetTestChild extends TargetTest {
@Override
public int add(int a, int b) {
// TODO Auto-generated method stub
return super.add(a, b);
}
}
第三步:
写测试类,TestTarget.java
import java.lang.annotation.Annotation;
public class TestTarget {
public static void main(String[] args) {
//实例化父类
TargetTest parent = new TargetTest();
//实例化子类
TargetTestChild child = new TargetTestChild();
//获取父类的类型
Class cls = TargetTest.class;
//获取子类的类型
Class childCls = TargetTestChild.class;
//获取父类的注解
Annotation[] pAnnotations = cls.getAnnotations();
if (pAnnotations.length > 0) {
System.out.println("父类的注解:");
for (Annotation annotation : pAnnotations) {
System.out.println(annotation.annotationType().getName());
}
}
//获取子类的注解
Annotation[] cAnnotations = childCls.getAnnotations();
if (cAnnotations.length > 0) {
System.out.println("子类的注解:");
for (Annotation annotation : cAnnotations) {
System.out.println(annotation.annotationType().getName());
}
}
}
}
该例子主要用到了java.lang.annotation.Annotation中的所有注解类型。对于Retention,Target,Inherited和Documented这是个注解类型,需要重点掌握前三个,第四个很少用到。
这上面的两个例子都能正常运行,我的环境依然是,JDK1.6。对于生成doc文档的问题,你也可以通过javadoc命令来生成,但是如果你的开发工具时myeclipse8.6的话,可以通过project->Generate Javadoc来生成doc文档,通过去掉和加上@Documented注解类型来观察在文档中是否有对应的说明(当然去掉或加上后需要重新生成下)。
这次先写到这里,关于注解在程序和框架中的应用案例,后面等我学习后会进行更新和发表,谢谢各位同行关注。
欢迎各位同行和前辈们提出问题,对程序或者我组织的语言进行批评指导。
相关推荐
Java 自定义注解验证是Java开发中的一个重要特性,它允许开发者创建自己的元数据,以便在编译时或运行时对代码进行验证和处理。自定义注解为代码提供了额外的信息,使得程序更具可读性、可维护性和灵活性。在本案例...
java自定义注解接口限流demo; java自定义注解接口限流demo; java自定义注解接口限流demo; java自定义注解接口限流demo; java自定义注解接口限流demo; java自定义注解接口限流demo; java自定义注解接口限流demo...
Java自定义注解是Java编程语言中的一个重要特性,它允许程序员在...自定义注解的灵活性和广泛用途使得它们成为现代Java开发不可或缺的一部分。在实际项目中,理解并熟练运用自定义注解能有效提高代码质量和可维护性。
Java自定义注解是Java语言中的一个重要特性,它允许我们创建自己的元数据,为代码提供额外的信息。在Java中,注解(Annotation)主要用于编译器检查、代码生成、运行时处理等方面。本文将深入探讨如何通过反射机制来...
"java自定义注解实践" Java 自定义注解实践是 Java 语言中的一项重要特性,它可以使开发者自定义注解,以满足不同的需求。在本文中,我们将详细介绍 Java 自定义注解的概念、特点、实现方式及实践应用。 概念 ----...
自定义注解是扩展Java功能的强大工具,可以用于实现各种目的,如代码生成、编译时检查、运行时处理等。在这个“自定义注解实现伪动态传参的小demo”中,我们将探讨如何创建一个自定义注解,以允许在注解中传递类似于...
Java自定义注解和通过反射获取注解是Java编程中重要的高级特性,它们极大地增强了代码的可读性和可维护性。注解(Annotation)是一种元数据,提供了在编译时和运行时对代码进行标记的方法,而反射(Reflection)则是...
在本案例中,我们将探讨如何利用自定义注解实现在Java类定义后自动创建对应的数据库表,以适应SQL Server和Oracle这样的关系型数据库。 首先,我们需要理解自定义注解的基本结构。在Java中,你可以通过`@interface`...
总的来说,Java的自定义注解为我们提供了强大的元数据功能,能够灵活地扩展代码的行为和语义。通过自定义注解,我们可以更优雅地实现代码的解耦,增加代码的可读性和可维护性。在自动售卖机的例子中,我们展示了如何...
Java自定义注解和Spring的BeanPostProcessor是Java企业级开发中的两个重要概念,它们在构建灵活、可扩展的应用程序中发挥着关键作用。本文将深入探讨这两个话题,并结合源码分析,帮助开发者更好地理解和应用。 ...
Java自定义注解是Java平台提供的一种元编程机制,它...通过自定义注解和处理器,开发者可以扩展Java语言,实现特定于应用的需求。在实际开发中,合理使用自定义注解可以提高代码的灵活性和可维护性,同时降低复杂性。
在Java编程语言中,自定义注解是一种强大的工具,它允许开发者创建自己的元数据,以提供额外的信息或规范代码的特定行为。自定义注解可以应用于类、接口、方法、变量等不同层级,使得代码更加模块化,易于理解和维护...
3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑...
在实际项目中,这一功能常与Java的Spring框架结合,利用其提供的`@Validated`注解和`Validator`接口。此外,还可以利用Apache POI库来读取和操作Excel文件,以及Hibernate Validator库来处理自定义注解的校验逻辑。 ...
Java 自定义注解的实例详解 Java 自定义注解是 Java 语言中的一种重要特性,它可以用于创建文档,跟踪代码中的依赖性,并且可以执行编译时期...通过掌握 Java 自定义注解,可以让开发者更好地控制和管理自己的代码。
以上就是利用自定义注解实现SQL拦截的基本原理和步骤,这个技术在处理复杂业务逻辑或者权限控制时非常有用,但同时也需要注意其潜在的风险和挑战。在实际项目中,应根据需求和项目规模合理使用。
以上就是关于Java自定义注解的基本概念、定义和使用方法。通过自定义注解,开发者可以更灵活地扩展Java语言的功能,实现更复杂的编程模式。在实际项目中,自定义注解常用于框架扩展、代码生成、验证规则设定等多种...
总之,这个压缩包的内容涵盖了Java自定义注解的基础知识,以及与Java Web相关的Tomcat服务器、用户会话管理等内容,对于理解和实践Java后端开发非常有帮助。通过深入学习这些材料,可以提高对Java编程和Web应用开发...
java 元注解+拦截器实现自定义注解 @CmwAutoWired:自定义依赖注入 注意:注入的接口和实现类需要在同一包名下,注解的是类则无限制 @FieldAnnotation:自定义属性注解 @MethodAnnotation:自定义方法注解 @...