一.定义
注解(annotation)也叫元数据,可以在指定位置标记可以在编译、类加载、运行时被读取,然后进行相应的处理。
二.常见的注解
[email protected]
当子类重写父类方法时,子类的该方法可以加入此注解。作用:确保子类确实重写了父类方法,且在父类删除该方法时,在子类中该错误会有错误提示。
[email protected]
该注解作用于方法和类上,标记改元素已过期,用户使用该方法或类时,编译器可以做出相应的警告,告诉用户不推荐使用。
[email protected]
用于通知java编译器禁止特定的编译警告。
三.注解的好处
1.现在的常用框架、工具等都广泛的应用了注解,使用时能够读懂别人的代码。
2.在不影响业务逻辑的情况下,与业务代码进行分离。
3.代替繁琐的xml配置
四.元注解
元注解是可以注解到其它注解上的注解,由jdk提供的一种最基本的注解。
[email protected]
Retention的英文意思是保留期。该注解标记了被注解的注解的生命周期。
该注解的值有:
- RetentionPolicy.SOURCE 该注解只在源代码上保留,在编译器编译时将会被忽略,更无法加载到JVM中,在运行时程序无法获取该注解的元信息。
- RetentionPolicy.CLASS 该注解在编译器保留,但无法加载到JVM中,在运行时无法获取到该注解的元信息。
- RetentionPolicy.RUNTIME 该注解在运行时保留,加载到JVM中,在运行时可以获取到该注解的元信息。
[email protected]
该注解与文档相关,它的作用是能够将注解中的元信息包含到javadoc中。
[email protected]
Target的英文意思是目标。该注解标记了注解运用的地方
该注解的值有:
- ElementType.ANNOTATION_TYPE 可以对一个注解进行注解。
- ElementType.CONSTRUCTOR 可以对构造方法进行注解。
- ElementType.FIELD 可以给属性进行注解。
- ElementType.LOCAL_VARIABLE 可以对局部变量进行注解。
- ElementType.METHOD 可以对方法进行注解。
- ElementType.PACKAGE 可以对包进行注解。
- ElementType.PARAMETER 可以对方法的参数进行注解。
- ElementType.TYPE 可以对类型进行注解,比如类、接口、枚举。
[email protected]
Inherited的英文意思是继承。它的作用是如果一个超类被该@Inherited注解过的注解注解,如果子类没有被任何注解注解的话,那么子类继承超类的注解。
[email protected]
Repeatable的英文意思是可重复的。它的作用的在同一个目标上能够应用多次。
五.注解的属性
注解的属性也叫注解的成员变量。需要注意的是,在注解中定义属性时它的类型必须是 8 种基本数据类型外加 类、接口、注解及它们的数组。
注解中属性可以有默认值,默认值需要用 default 关键值指定。
代码示例:
1 |
(RetentionPolicy.RUNTIME) |
六.提取注解
###1.注解通过反射获取。
首先可以通过Class对象的isAnnotation()方法判断它是否应用了某个注解,方法原型:
1 |
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass); |
然后通过getAnnotation()获取Annotation对象,方法原型:
1 |
public <A extends Annotation> A getAnnotation(Class<A> annotationClass); |
当然,可以通过getAnnotations() 获取注解列表,方法原型:
1 |
public Annotation[] getAnnotations(); |
2.获取元数据
获取到Annotation对象后,通过对应的方法获取值,示例代码(对应以上TestAnnotion):
1 |
if (Main.class.isAnnotationPresent(TestAnnotation.class)){ |
七.示例
1.目的
使用注解给方法标记,通过注解获取数据源。
2.编写主从数据库主从枚举类
1 |
public enum DataSourceType { |
3.自定义一个注解TestAnnotation
1 |
(RetentionPolicy.RUNTIME) |
4.数据库查询类
1 |
public UserDbHelper{ |
5.主类
1 |
public class Main{ |
最终程序输出:SLAVE
八.后记
在示例代码中,只是获取到标记的内容并输出,并没有达到动态切换数据源的目的。如果需要,则需要使用aop在selectByPrimaryKey方法设置切点,在调用该方法前,在切面中,通过注解获取该方法的DataSource注解,通过该注解获取标记DataSourceType,然后切换数据源为DataSourceType对应的据源,来达到动态数据源的目的。在该方法执行完后,再切换为MASTER数据源。




近期评论