`

注解-自定义注解原理

    博客分类:
  • java
阅读更多

注解是代码的附属信息,它遵循一个基本原则:注解不能直接干扰程序代码的运行,无论增加或删除注解,代码都能够正常运行。

Java语言解释器会忽略这些注解,而由第三方工具负责对注解进行处理。第三方工具可以利用代码中的注解间接控制程序代码的运行,它们通过Java反射机制读取注解的信息,并根据这些信息更改目标程序的逻辑,而这正是Spring AOP对@AspectJ提供支持所采取的方法。

 

注解的语法比较简单,除了@符号的使用以外,它基本上与java的固有语法一致,java内置了三种注解,定义在java.lang包中。

@Override:只能用在方法之上的,用来告诉别人这一个方法是改写父类的。

@Deprecated:建议别人不要使用旧的API的时候用的,编译的时候会用产生警告信息,可以设定在程序里的所有的元素上。

@SuppressWarnings:表示关闭一些不当的编译器警告信息。

 

定义注解

下面是一个定义注解的实例。

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

public @interface Description {

 String value();

}

 

其中的@interface是一个关键字,在设计annotations的时候必须把一个类型定义为@interface,而不能用class或interface关键字。

所有的注解类都隐式继承于 java.lang.annotation.Annotation,注解不允许显式继承于其他的接口。

 

一个注解可以拥有多个成员,成员声明和接口方法声明类似,这里,我们仅定义了一个成员,成员的声明有以下几点限制:

a)成员以无入参无抛出异常的方式声明,如boolean value(String str)、boolean value() throws Exception等方式是非法的;

b)可以通过default为成员指定一个默认值,如String level() default "LOW_LEVEL"、int high() default 2是合法的,当然也可以不指定默认值;

c)成员类型是受限的,合法的类型包括原始类型及其封装类、String、Class、enums、注解类型,以及上述类型的数组类型。如ForumService value()、List foo()是非法的。

d)如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=),如@Description("使用注解的实例")。

注解类拥有多个成员时,如果仅对value成员进行赋值则也可不使用赋值号,如果同时对多个成员进行赋值,则必须使用赋值号,如@DeclareParents (value = "NaiveWaiter", defaultImpl = SmartSeller.class)。

e)注解类可以没有成员,没有成员的注解称为标识注解,解释程序以标识注解存在与否进行相应的处理;

 

注解定义包含四个元注解,分别为@Target,@Retention,@Documented,@Inherited。各元注解的作用如下:

1)  @Target

表示该注解用于什么地方,可能的 ElemenetType 参数包括:

Ø  ElemenetType.CONSTRUCTOR 构造器声明。

Ø  ElemenetType.FIELD 域声明(包括 enum 实例)。

Ø  ElemenetType.LOCAL_VARIABLE 局部变量声明。

Ø  ElemenetType.METHOD 方法声明。

Ø  ElemenetType.PACKAGE 包声明。

Ø  ElemenetType.PARAMETER 参数声明。

Ø  ElemenetType.TYPE 类,接口(包括注解类型)或enum声明。

 

2)  @Retention

表示在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括:

Ø  RetentionPolicy.SOURCE 注解将被编译器丢弃。

Ø  RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃。

Ø  RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。

举一个例子,如@Override里面的Retention设为SOURCE,编译成功了就不要这一些检查的信息,相反,@Deprecated里面的Retention设为RUNTIME,表示除了在编译时会警告我们使用了哪个被 Deprecated的方法,在执行的时候也可以查出该方法是否被Deprecated。

 

3)@Documented

将此注解包含在javadoc中

 

4)@Inherited

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

 

使用注解

下面是一个使用注解的实例。

@Description(value="使用注解的实例")
public class TestAnnotation {
}

 

解析注解

下面是一个解析注解的实例。

public class ParseAnnotation {
 public static void main(String[] args) throws Exception{
  final Class cls = Class.forName("com.annotation.TestAnnotation");
  final Method[] method = cls.getMethods();
  // 判断是否有指定注解类型的注解
  if(cls.isAnnotationPresent(Description.class)) {
   // 根据注解类型返回指定类型的注解
   Description des = (Description)cls.getAnnotation(Description.class);
   System.out.println("注解描述:" + des.value());
  }
 }
}

输出结果如下:

注解描述:使用注解的实例

 

前面提到过,注解不会直接影响程序的运行,但是第三方程序或工具可以利用代码中的注解完成特殊的任务,间接控制程序的运行。

对于RetentionPolicy.RUNTIME保留期限的注解,我们可以通过反射机制访问类中的注解。

 

spring的@Autowired等注解,就是注解解释器(第三方程序)在注入完成后,在构造方法中,通过反射给@Autowired的字段注入bean。

 

在JDK5.0里,Package、Class、Constructor、 Method以及Field等反射对象都新增了访问注解信息的方法:<T extends Annotation>T getAnnotation(Class<T> annotationClass),该方法支持通过泛型直接返回注解对象。 

分享到:
评论

相关推荐

    Spring学习笔记(11)----自定义属性编辑器

    首先,我们需要了解属性编辑器的工作原理。当IoC容器读取配置文件时,如果发现一个属性值需要转化为特定的对象类型,它会自动寻找合适的属性编辑器。Spring提供了一系列内置的属性编辑器,如`StringToBooleanEditor`...

    java 自定义注解验证

    Java 自定义注解验证是Java开发中的一个重要特性,它允许开发者创建自己的元数据,以便在编译时或运行时对代码进行验证和处理。自定义注解为代码提供了额外的信息,使得程序更具可读性、可维护性和灵活性。在本案例...

    aixos-ts-encapsulation_自定义注解_

    在IT行业中,尤其是在软件开发领域,注解(Annotation)是一种非常重要的编程概念,它...通过理解自定义注解的工作原理以及如何在TypeScript环境中使用它们,开发者可以更好地利用这一强大的工具来优化他们的应用程序。

    JAVA 注解---积累

    在Java编程语言中,注解(Annotation)是一种元数据,它提供了一种安全的方法来将信息...这篇博客可能深入探讨了注解的原理、自定义注解的创建、以及注解在实际项目中的应用,对于Java开发者来说是一份宝贵的参考资料。

    注解Annotation实现原理与自定义注解例子.pdf

    注解Annotation实现原理与自定义注解例子 每当你创建描述符性质的类或者接口时,一旦其中包含重复性的工 作,就可以考虑使用注解来简化与自动化该过程。 Java提供了四种元注解,专门负责新注解的创建工作

    自定义注解实现拦截sql.rar

    以上就是利用自定义注解实现SQL拦截的基本原理和步骤,这个技术在处理复杂业务逻辑或者权限控制时非常有用,但同时也需要注意其潜在的风险和挑战。在实际项目中,应根据需求和项目规模合理使用。

    Spring高级之注解驱动开发视频教程

    从应用场景分析,到基本用法的入门案例,再到高级特性的分析及使用,最后是执行原理的源码分析。让学生通过学习本套课程不仅可以知其然,还可以知其所以然。最终通过一个综合案例,实现灵活运用Spring框架中的各个...

    自定义注解案例

    在Java编程语言中,自定义注解是一种强大的工具,它允许程序员定义自己的元数据,以提供额外的信息给编译器、运行时环境或其他工具。...通过研究这个案例,你将更深入地理解自定义注解在实际项目中的工作原理和用途。

    spring aop 自定义注解保存操作日志到mysql数据库 源码

    3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑...

    自定义注解实现IOC,代替findviewbyid,setcontentview,setListener

    为了解决这些问题,我们可以采用自定义注解实现Inversion of Control(IoC,控制反转)和Dependency Injection(DI,依赖注入)来简化代码,提高可读性和可测试性。本文将深入探讨如何通过自定义注解来实现这一目标...

    Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源

    本项目“Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源”正是针对这一需求提供的一种解决方案。下面将详细介绍这个项目中的关键技术点和实现原理。 首先,Spring框架是Java企业级应用开发的核心...

    这一次搞懂Spring自定义标签以及注解解析原理说明

    在Spring框架中,自定义标签和注解解析是两个关键的特性,它们使得代码与配置的集成更加紧密,简化了应用程序的开发。本篇文章将深入探讨Spring如何处理这两种类型的元数据。 首先,让我们来理解Spring如何解析...

    Spring IOC 原理 ,Java 反射实例,自定义注解

    在Spring中,我们可以使用`@ComponentScan`或`@Configuration`配合`@Autowired`,扫描带有自定义注解的类并自动装配它们。Spring的AOP(面向切面编程)也支持自定义注解,用于实现如日志记录、事务管理等跨切面关注...

    springBoot+aop+自定义注解+本地线程实现统一接口日志及接口响应时长

    核心原理:通过自定义注解实现每个接口的描述及所在模块还有接口的操作类型,通过拦截器及访问方法后的切面aop记录接口的总耗时,在接口请求前在本地线程记录请求的参数,接口请求后记录返回参数及记录请求日志 ...

    spring中注解的实现原理

    通过实现`BeanFactoryPostProcessor`或`BeanPostProcessor`接口,你可以扩展Spring的行为,使其在处理自定义注解时执行特定的操作。 总结来说,Spring中注解的实现原理涉及到元注解的定义、注解处理器的运行、Bean...

    Gradle中如何自定义实现Java注解处理器

    在提供的文件列表中,虽然没有具体的源代码示例,但我们可以假设`annotation`目录可能包含了自定义注解的定义,而`demo`目录可能包含使用这些注解的实际应用。`build.gradle`和`settings.gradle`文件是Gradle项目的...

    springboot2基础运维开发实用到原理课 视频教程 下载 因为太大存百度云盘3.zip

    150-原理篇-bean加载控制(注解式).mp4 151-原理篇-bean依赖属性配置.mp4 152-原理篇-自动配置思想.mp4 153-原理篇-自动配置原理(1).mp4 154-原理篇-自动配置原理(2).mp4 155-原理篇-自动配置原理...

    springboot2基础运维开发实用到原理课 视频教程 下载 因为太大存百度云盘2.zip

    150-原理篇-bean加载控制(注解式).mp4 151-原理篇-bean依赖属性配置.mp4 152-原理篇-自动配置思想.mp4 153-原理篇-自动配置原理(1).mp4 154-原理篇-自动配置原理(2).mp4 155-原理篇-自动配置原理...

    springboot2基础运维开发实用到原理课 视频教程 下载 因为太大存百度云盘4.zip

    150-原理篇-bean加载控制(注解式).mp4 151-原理篇-bean依赖属性配置.mp4 152-原理篇-自动配置思想.mp4 153-原理篇-自动配置原理(1).mp4 154-原理篇-自动配置原理(2).mp4 155-原理篇-自动配置原理...

    springboot2基础运维开发实用到原理课 视频教程 下载 因为太大存百度云盘1.zip

    150-原理篇-bean加载控制(注解式).mp4 151-原理篇-bean依赖属性配置.mp4 152-原理篇-自动配置思想.mp4 153-原理篇-自动配置原理(1).mp4 154-原理篇-自动配置原理(2).mp4 155-原理篇-自动配置原理...

Global site tag (gtag.js) - Google Analytics