- 浏览: 706015 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (272)
- Struts1.x (7)
- 事务 (2)
- Hibernate (11)
- 数据库 (14)
- JavaScript&Ajax (43)
- JSP&Servlet (2)
- Flex (1)
- 其它 (9)
- Java (22)
- 框架集成 (1)
- WebService (3)
- Tomcat (3)
- 加密和安全登录 (13)
- 基于原型的JavaScript (0)
- JavaDoc和Java编码规范 (3)
- CAS (1)
- 加密 (1)
- Axis2 (10)
- Ext2.x (3)
- SSH整合 (2)
- Ext (0)
- 正则表达式 (1)
- 设计模式 (4)
- 对象序列化技术 (3)
- CVS (2)
- Struts2 (6)
- Spring 2.x (7)
- Spring Security (2)
- Java 课程 (20)
- 程序员之死 (1)
- 软件测试 (6)
- UML (5)
- NetBeans (1)
- cxf (1)
- JMS (13)
- 设计 (5)
- ibatis2.x (3)
- Oracle (1)
- WebSphere (7)
- 概要设计 (1)
- DB2 (10)
- PowerDesigner (0)
- 软件工程 (5)
- rose (1)
- EA (1)
- LDAP (7)
- Portal&Portlet (3)
- MQ (10)
- ESB (4)
- EJB (2)
- JBoss (2)
最新评论
-
typeRos:
只有配置文件,没有代码么大神
Spring实现IBMMQ的JMS消息发布/订阅模式 -
panamera:
如果ActiveMQ服务器没有启动,这个时候消息生产者使用Jm ...
Spring JMSTemplate 与 JMS 原生API比较 -
lian819:
顶1楼, 引用文件, 配置属性, 太方便了
EXTJS 同步和异步请求 -
wilhard:
说得清楚明白
<%@ include file=""%>与<jsp:include page=""/>区别 -
刘琛颖:
总结的很好。受益了
javascript 父窗口(父页面)— 子窗口 (子页面)互相调用的方法
从 JDK 5.0 开始,Java 增加了对元数据 (MetaData)的支持,也就是 Annotation (注释)。用 Annotation 程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充的信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
Annotation 提供了一条为程序元素设置元数据的方法,从某些方面来看,Annotation 就像修饰符一样被使用,可以用于修饰包、类、构造器、方法、成员变量、参数、局部变量的声明,这些信息被保存在 Annotation 的 “name=value” 对中。
Annotation 是一个接口,程序可以通过反射来获取指定程序元素的 Annotation 对象,然后通过 Annotation 对象来取得注释里的元数据。
一、基本的 Annotation
Java 提供的三个基本 Annotation 的用法:使用 Annotation 时要在其前面增加 @ 符号,并把该 Annotation 当成一个修饰符使用,用于修饰它支持的的程序元素:
- @Override
- @Deprecated
- @SuppressWarnings
Java 提供的三个基本Annotation 都定义在 java.lang 包下。
1、限定重写父类方法:@Override
@Override 就是用来指定方法覆载的,它可以强制一个子类必须要覆盖父类的方法
示例:
public class Fruit
{
public void info()
{
System.out.println("水果的info方法。。。");
}
}
class Apple extends Fruit
{
//使用@Override指定下面方法必须重写父类方法
@Override
// public void info()
public void inf0()
{
System.out.println("苹果重写水果的info方法。。。");
}
}
2、标示已过时:@Deprecated
示例:
class Apple
{
//定义info方法已过时
@Deprecated
public void info()
{
System.out.println("Apple的info方法");
}
}
public class DeprecatedTest
{
public static void main(String[] args)
{
//下面使用info方法时将会被编译器警告
new Apple().info();
}
}
3、抑制编译器警告
示例:取消没有泛型限制的集合引发的编译器警告
@SuppressWarnings(value="unchecked")
public class SuppressWarningsTest
{
public static void main(String[] args)
{
List<String> myList = new ArrayList();
}
}
二、自定义 Annotation
1、定义 Annotation
定义新的 Annotation 类型使用 @interface 关键字,例如:
// 定义一个简单的 Annotation 类型
public @interface Test
{}
使用 Test 注释:
// 用 @Test 修饰类定义
@Test
public class MyClass
{
……
}
默认情况下,Annotation 可用于修饰任何程序元素,包括类、接口、方法等。
public class MyClass
{
// 使用 @Test Annotation 修饰方法
@Test
public void info()
{
……
}
……
}
定义带成员变量的 Annotation,Annotation 的成员变量在 Annotation 定义中以无参数方法的形式声明,其方法名和返回值定义了该成员变量的名字和类型。示例:
public @interface MyTag
{
// 定义两个成员变量的 Annotation
// Annotation 中的成员变量以方法的形式定义
String name();
int age();
}
使用带成员变量的 Annotation:
public class Test
{
// 使用带成员变量的 Annotation 时,需要为成员变量赋值
@MyTag(name="xx", age=6)
public void info()
{
……
}
……
}
还可以在定义 Annotation 的成员变量时为其指定初始值,使用 default 关键字,示例:
public @interface MyTag
{
String name() default "liuchuanfeng";
int age() default 16;
}
如果为 Annotation 的成员变量指定了默认值,使用该 Annotation 则可以不为这些成员变量指定值,而是直接使用默认值。
2、提取 Annotation 的信息
Java 使用 Annotation 接口来代表程序元素前面的注释,该接口是所有 Annotation 类型的父接口,除此之外,Java 在 java.lang.reflect 包下新增了 AnnotatedElement 接口,该接口代表程序中可以接受注释的程序元素,该接口主要有以下几个实现类:
- Class:类定义
- Constructor:构造器定义
- Field:类成员变量定义
- Mehtod:类的方法定义
- Package:类的包定义
AnnotatedElement 接口是所有程序元素(如:Class、Mehtod、Constructor)的父接口,所以程序通过反射获得了某个类的 AnnotatedElement 对象(如:Class、Mehtod、Constructor)之后,程序就可以调用对象的如下三个方法来访问 Annotation 的信息:
- getAnnotation(Class<T> annotationClass):返回该程序元素上存在的、指定的类型的注释,如果该类型的注释不存在,则返回 null
- Annotation[] getAnnotations():返回程序元素上存在的所有注释
- boolean isAnnotationPresent(Class<? extends Annotation> annotationClass):判断该程序元素上是否包含指定类型的注释,存在则返回 true,否则返回 false
示例:下面程序片段用于获取 Test 类 info 方法里的所有注释:
Annotation[] aArray = Class.forName("Test").getMethod("info").getAnnotations();
for (Annotation an : aArray)
{
System.out.println(an);
}
如果需要获取某个注释里的元数据,则可以将注释强制类型转换成所需要的注释类型,然后通过注释对象的抽象方法来访问这些数据,如:
Annotation[] annotation = tt.getClass().getMethod("info").getAnnotations();
// 遍历每个注释对象
for (Annotation tag : annotation)
{
// 如果 tag 注释是 MyTag1 类型
if(tag instanceof MyTag1)
{
System.out.println("Tag is:" + tag);
System.out.println("tag.name(): " + ((MyTag1) tag).method1());
System.out.println("tag.age(): " + ((MyTag1) tag).method2());
}
// 如果 tag 注释是 MyTag2 类型
if(tag instanceof MyTag2)
{
System.out.println("Tag is:" + tag);
System.out.println("tag.name(): " + ((MyTag2) tag).method1());
System.out.println("tag.age(): " + ((MyTag2) tag).method2());
}
}
3、使用 Annotation 的例子
Annotation Testable 没有成员变量,仅仅是一个标记 Annotation,它的作用是标记哪些方法是可测试的。
Testable.java:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
//定义一个标记注释,不包含任何成员变量,即不可传入元数据
public @interface Testable
{
}
MyTest 测试用例里定义了 8 个方法,这 8 个方法没有太大的区别,其中四个方法是用 @Testable 注释来标记这些方法是可测试的。
MyTest
MyTest.java:
public class MyTest
{
//使用@Testable标记注释指定该方法是可测试的
@Testable
public static void m1()
{
}
public static void m2()
{
}
//使用@Testable标记注释指定该方法是可测试的
@Testable
public static void m3()
{
throw new RuntimeException("Boom");
}
public static void m4()
{
}
//使用@Testable标记注释指定该方法是可测试的
@Testable
public static void m5()
{
}
public static void m6()
{
}
//使用@Testable标记注释指定该方法是可测试的
@Testable
public static void m7()
{
throw new RuntimeException("Crash");
}
public static void m8()
{
}
}
仅仅使用注释来标识程序元素对程序是不会有任何影响的,这也是 Java 注释的一条重要原则,为了让程序中这些注释起作用,我们必须为这些注释提供一个注释处理工具。
下面的注释处理工具会分析目标类,如果目标类中方法使用了@Testable 注释修饰,则通过反射运行该测试方法。
public class TestProcessor
{
public static void process(String clazz) throws ClassNotFoundException
{
int passed = 0;
int failed = 0;
// 遍历 obj 对象的所有方法
for (Method m : Class.forName(clazz).getMethods())
{
// 如果包含 @Testable 标记注释
if(m.isAnnotationPresent(Testable.class))
{
try
{
// 调用 m 方法
m.invoke(null);
// passed 加 1
passed++;
}
catch(Exception ex)
{
System.out.printf("方法" + m + "运行失败,异常:" + ex.getCause() + "\n");
failed++;
}
}
}
// 统计测试结果
System.out.printf("共运行了:" + (passed + failed)+ "个方法,其中:\n" +
"失败了:" + failed + "个,\n" +
"成功了:" + passed + "个!\n");
}
}
主函数类:RunTests.java
public class RunTests
{
public static void main(String[] args) throws Exception
{
// 处理 MyTest 类
TestProcessor.process("MyTest");
}
}
带成员变量的 Annotation 示例:
ActionListenerFor.java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ActionListenerFor
{
// 定义一个成员变量,用于设置元数据
// 该 listener 成员变量用于保存监听器实例
String listener();
}
public class AnnotationTest
{
private JFrame mainWin = new JFrame("使用注释绑定事件监听器");
// 使用注释为 ok 按钮绑定事件监听器
@ActionListenerFor(listener="OkListener")
private JButton ok = new JButton("确定");
// 使用注释为 cancel 按钮绑定事件监听器
@ActionListenerFor(listener = "CancelListener")
private JButton cancel = new JButton("取消");
public void init()
{
// 初始化主界面
JPanel jp = new JPanel();
jp.add(ok);
jp.add(cancel);
mainWin.add(jp);
ActionListenerInstaller.processAnnotations(this); // ①
mainWin.setDefaultCloseOption(JFrame.EXIT_ON_CLOSE);
mainWin.pack();
mainWin.setVisible(ture);
}
public static void main(String[] args)
{
new AnnotationTest.init();
}
}
// 定义 ok 按钮的事件监听器实现类
class OkListener implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
JOptionPane.show(null, "点击了确认按钮");
}
}
// 定义 cancel 按钮的事件监听器实现类
class CanelListener implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
JOptionPane.show(null, "点击了取消按钮");
}
}
正如前面提到,如果仅仅在程序中使用注释是不会有任何作用的,必须使用注释处理工具来处理程序中的注释。程序中 ① 处代码使用了 ActionListenerInstaller 来处理本程序中的注释,该处理器分析目标对象中所有的 Field,如果该 Field 前使用了 ActionListenerFro Annotation,则取出该 Annotation 中的 listener 元数据,并根据该数据来绑定事件监听器。
ActionListenerInstaller.java
public class ActionListenerInstaller
{
try
{
// 获取 obj 对象的类
Class c1 = obj.getClass();
// 获取指定的 obj 对象中所有的 Field,并遍历每个 Field
for (Field f : c1.getDeclaredFields())
{
// 将指定 Field 设置成可自由访问的,避免 private 的 Field 不可访问
f.setAccessible(true);
// 获取指定 Field 的 ActionListenerFor 类型的注释
ActionListenerFor a = f.getAnnotation(ActionLinstenerFor.class);
if (a != null && a instanceof AbstractButton)
{
// 获取 a 注释里的元数据 listener (它是一个监听器类)
Class listenerClazz = Class.forName(a.listener());
// 使用反射来创建 listener 类的对象
ActionListener al = listenerClazz.newInstance();
// 获取 f Field 实际对应的对象
AbstractButton b = (AbstractButton) f.get(obj);
//为ab对象添加事件监听器
ab.addActionListener(al);
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
三、JDK 的元 Annotation
JDK 除了在 java.lang 下提供了 3 个基本 Annotation 之外,还在 java.lang.annotation 包下提供了四个 Meta Annotation (元 Annotation),这四个 Annotation 都是用来修饰其他的 Annotation 定义。
1、使用 @Retention
@Retention 只能用于修饰一个 Annotation 定义,用于指定该 Annotation 可以保留多长时间,@Retention 包含一个 RetentionPolicy 类型的 value 成员变量,
value 成员变量的值只能有如下三个:
- RetentionPolicy.CLASS:编译器将吧主是记录在 class 文件中。当运行 Java 程序时,JVM 不再保留注释。这是默认值
- RetentionPolicy.CLASS:编译器将吧主是记录在 class 文件中。当运行 Java 程序时,JVM 也会保留注释,程序可以通过反射获取该注释
- RetentionPolicy.CLASS:编译器直接丢弃这种策略的注释
2、使用 @Target
@Target 用于指定被修饰的 Annotation 能用于修饰哪些程序元素,它也包含一个名为 value 的成员变量,该成员变量的值只能是如下几个:
@Target 用于指定被修饰的 Annotation 能用于修饰哪些程序元素,它也包含一个名为 value 的成员变量,该成员变量的值只能是如下几个:
- ElementType.ANNOTATION_TYPE
- ElementType.CONSTRUCTOR
- ElementType.FIELD
- ElementType.LOCAL_VARIABLE
- ElementType.METHOD
- ElementType.PACKAGE
- ElementType.PARAMETER
- ElementType.TYPE
3、使用 @Documented
@Documented 用于指定被该元 Annotaton 修饰的 Annotation 类将被 javadoc 工具提取成文档,如果定义 Annotation 类时使用了 @Documented 修饰,则所有使用该 Annotation 修饰的程序元素的 API 文档中将会包含该 Annotation 说明
发表评论
-
java:comp/env 解释
2012-07-13 13:40 10841关于获取数据源的语法,大体有(javax.sql.D ... -
java.naming.factory.url.pkgs 的用途
2012-06-28 09:48 1760原文地址:http://blog.csdn.net/l ... -
解析 HTTP
2010-11-14 18:09 48063、HTTP 请求 客户端通过发送 HTTP 请求向服务器 ... -
Tomcat server.xml 文件
2010-11-07 17:21 1228Tomcat 服务器有一系列可配置的组件构成,这些组件 ... -
Tomcat的体系结构
2010-11-04 21:13 1483Tomcat的体系结构 Tomcat服务器是由一系列可配 ... -
第十四课时: 输入/输出1
2010-10-30 20:48 1321Java 的 IO 支持通过 java.io 包 ... -
第十七课时: 网络编程
2010-10-18 22:00 1153一. 网络编程的基础知 ... -
第十六课时: 多线程
2010-10-07 14:24 981一. 继承 Thread 类创建线程 通过继承 Thread ... -
第十四课时:输入/输出2
2010-09-05 15:54 1254... -
第十二课时:JDBC 编程 (2)
2010-08-28 13:13 878示例: import java.sql.*; impor ... -
第十二课时:JDBC 编程 (1)
2010-08-08 15:52 2104一、SQL 语句基础 SQL 的全称是 Structured ... -
第11课时:异常处理
2010-07-25 16:51 1151一、异常处理机制 1、使用 try...catch 捕获异常 ... -
第十课时:与运行环境交互
2010-07-24 06:03 779一、与用户交互 1、使用 Scanner 获取键盘输入 获 ... -
第九课时:泛型
2010-07-11 17:00 1387一、定义泛型接口、类 JDK 1.5 改写了 ... -
第六课时:面向对象(5)—— 2010年05月22日
2010-07-04 13:45 991一、内部类 在某些情况下,我们把一个类放在另一个类的 ... -
第三课时:面向对象(2)
2010-05-02 23:20 1424一、成员变量与局部变量 二、类的继 ... -
第二课时:数组、面向对象(1)
2010-05-02 23:19 961一、数组 1、 ... -
第四课时:面向对象(3)
2010-05-02 23:17 903一、基本数据类型的包装类 1、 基本数据类型和包装 ... -
第一课时提纲:Java 基础(GC)
2010-03-22 23:22 1189一、Java 命名规范 1、对常量的命名规范: ...
相关推荐
然而,在使用`<mvc:annotation-driven />`元素时,有时会出现与自定义拦截器的冲突问题。这个问题通常出现在当我们试图同时配置基于注解的控制器处理和自定义拦截器时,Spring可能无法正确地处理这些组件的执行顺序...
在Spring MVC框架中,`mvc:annotation-driven`是Spring MVC配置中的一个重要元素,它使得我们的应用能够支持基于注解的控制器、数据绑定、格式化转换器和服务端验证等功能。这篇博客将深入探讨`mvc:annotation-...
在Spring MVC框架中,`mvc:annotation-driven`和`mvc:message-converters`是两个非常重要的元素,它们在处理基于注解的控制器和数据转换方面起着关键作用。本篇文章将深入探讨这两个组件的工作原理以及如何在实际...
赠送jar包:jakarta.annotation-api-1.3.5.jar; 赠送原API文档:jakarta.annotation-api-1.3.5-javadoc.jar; 赠送源代码:jakarta.annotation-api-1.3.5-sources.jar; 赠送Maven依赖信息文件:jakarta.annotation...
首先,`<mvc:annotation-driven/>`的作用是自动配置Spring MVC,启用对处理方法注解的支持,如`@RequestMapping`、`@RequestParam`、`@ModelAttribute`等。通过这个元素,我们可以避免编写大量的XML配置,转而采用...
Spring 的 Annotation-Driven 配置事务管理器详解(多数据源配置) Spring 框架提供了强大的事务管理机制,通过使用 Annotation-Driven 配置,可以方便地管理事务。在多数据源配置中,spring 的 Annotation-Driven...
赠送jar包:jakarta.annotation-api-1.3.5.jar; 赠送原API文档:jakarta.annotation-api-1.3.5-javadoc.jar; 赠送源代码:jakarta.annotation-api-1.3.5-sources.jar; 赠送Maven依赖信息文件:jakarta.annotation...
赠送jar包:javax.annotation-api-1.2.jar; 赠送原API文档:javax.annotation-api-1.2-javadoc.jar; 赠送源代码:javax.annotation-api-1.2-sources.jar; 赠送Maven依赖信息文件:javax.annotation-api-1.2.pom;...
赠送jar包:javax.annotation-api-1.3.2.jar; 赠送原API文档:javax.annotation-api-1.3.2-javadoc.jar; 赠送源代码:javax.annotation-api-1.3.2-sources.jar; 赠送Maven依赖信息文件:javax.annotation-api-...
androidx-annotation-1.2.0.jar
@androidx.annotation.NonNull 缺失的兼容、androidx.annotation兼容包
在Spring框架中,注解(Annotation)支持是其核心特性之一,它极大地简化了配置,提高了代码的可读性和可维护性。这篇博客"spring源代码分析:annotation支持的实现"探讨了Spring如何通过注解处理来实现组件扫描和...
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @...
androidx-annotation-1.0.0.jar
本篇文章将聚焦于MyBatis中的注解(Annotation)与XML配置的结合使用,旨在帮助开发者更深入地理解这一关键特性。 首先,MyBatis允许我们使用注解来简化Mapper接口的定义,无需编写XML映射文件。例如,我们可以在...
Pixel Annotation_ToolAboutPixel Annotation Tool is a chrome extension to generate Pixel Rule (which used by pixeljs or python module) by annotation in browser.It can both used for ...
赠送jar包:geronimo-annotation_1.0_spec-1.1.1.jar; 赠送原API文档:geronimo-annotation_1.0_spec-1.1.1-javadoc.jar; 赠送源代码:geronimo-annotation_1.0_spec-1.1.1-sources.jar; 赠送Maven依赖信息文件:...
赠送jar包:javax.annotation-api-1.2.jar; 赠送原API文档:javax.annotation-api-1.2-javadoc.jar; 赠送源代码:javax.annotation-api-1.2-sources.jar; 赠送Maven依赖信息文件:javax.annotation-api-1.2.pom;...
Java 1.5 引入了一种新的元编程机制——注解(Annotation),极大地增强了代码的可读性和可维护性。注解是一种在代码中添加元数据的方式,它允许程序员在源代码上添加一些信息,这些信息可以被编译器或运行时环境...