注解(Annotation)原理与自定义注解实战:你不懂的注解背后究竟发生了什么?
开篇语
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!
前言
在 Java 编程中,注解(Annotation)这一概念虽然很常见,但很多开发者在使用时,可能只是停留在“用来做标记、配置”这一层面。你是不是也觉得,注解就是加在类、方法、字段前面的一些小符号,能够影响程序的行为,但并没深究过它背后的原理和使用技巧?
其实,注解在 Java 中扮演着非常重要的角色,它不仅仅是“装饰器”,更是编译期、类加载期甚至运行时的一种强大工具。今天,我们不仅要了解注解的基本原理,还将通过自定义注解的实战,带你进入注解的“魔法世界”,让你不再仅仅满足于“好用”,而是深入理解注解背后的设计思想和应用场景。
所以,坐稳了,接下来我们一起深入探索注解的奥秘,搞定自定义注解这门“黑魔法”!
一、注解是什么?
注解,从字面上来看,它就是对代码的元数据注解。也就是说,它不会直接影响程序的逻辑行为,但能通过某些工具或框架读取并执行对应的功能。Java 中的注解并不是程序执行的一部分,而是用来描述程序的结构、元信息,甚至在特定的情况下改变程序的行为。
注解的基本用法
注解的定义非常简单,语法结构类似于接口。常见的注解如 @Override、@Deprecated、@Entity 等。它们一般不会影响程序的执行,而是给编译器或者运行时提供一些额外的信息。
// 使用 @Override 注解表示该方法重写了父类的方法
@Override
public String toString() {
return "Hello, World!";
}
// 使用 @Deprecated 注解表示该方法已过时,不推荐使用
@Deprecated
public void oldMethod() {
System.out.println("This method is outdated!");
}
1. 基本语法
@interface MyAnnotation {
// 定义一个注解
String value() default "Default";
}
简单来说,注解就是用 @ 开头的特殊标记,它可以附加在类、方法、字段、参数等位置。
二、注解的原理:编译期、类加载期、运行时的作用
1. 编译期(注解不参与程序运行)
注解可以在编译时用于检查,比如 @Override,它会帮助编译器检查我们是否真正重写了父类方法。如果我们用 @Override 注解修饰的方法在父类中不存在,编译器会报错。
@Override
public void someMethod() { // 编译期检查父类是否有该方法
System.out.println("Hello");
}
2. 类加载期(注解可以用作元数据)
注解还可以在类加载期间用于一些框架或工具类的处理,比如 Spring 框架就是通过注解(如 @Autowired)来实现依赖注入的。
3. 运行时(注解的核心应用)
注解的最强大之处是在运行时,它能通过反射机制被程序读取并执行。比如使用 @Entity 注解标记的类,ORM 框架(如 Hibernate)会在程序启动时通过反射读取注解信息,进而将该类映射成数据库表。
@Entity
public class User {
@Id
private Long id;
private String name;
}
三、注解的分类
Java 中的注解有多种分类方式,按照作用域和生命周期,常见的分类方式如下:
-
标准注解(Built-in Annotations)
@Override:标识重写父类的方法。@Deprecated:标记该方法或类已经不推荐使用。@SuppressWarnings:抑制编译器警告。
-
元注解(Meta-Annotations)
@Retention:定义注解的生命周期。@Target:指定注解可以应用于哪些元素(类、方法、字段等)。@Inherited:使得注解可以从父类继承到子类。@Documented:使注解能够包含在 Javadoc 中。
-
自定义注解(Custom Annotations)
我们可以根据需要自定义注解,下面将通过一个实际的案例来演示如何定义和使用自定义注解。
四、自定义注解实战:我们来造一个“黑魔法”注解
1. 定义一个自定义注解
我们先定义一个注解,用于标记方法是否需要进行日志记录。
// 定义注解
@Retention(RetentionPolicy.RUNTIME) // 注解在运行时有效
@Target(ElementType.METHOD) // 注解只能应用于方法上
public @interface LogExecutionTime {
// 你可以在注解中定义元素,作为附加信息
}
这里的 @Retention(RetentionPolicy.RUNTIME) 表示注解会在运行时通过反射获取,@Target(ElementType.METHOD) 表示注解只能用在方法上。
2. 使用自定义注解
接下来我们用这个注解来标记需要记录执行时间的方法:
public class MyService {
@LogExecutionTime // 标记需要记录执行时间
public void processData() {
// 模拟一些耗时操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3. 创建注解处理器(处理注解逻辑)
接下来,我们创建一个注解处理器,通过反射扫描 @LogExecutionTime 注解,并记录方法的执行时间:
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class LogExecutionTimeProcessor {
public static void process(Object object) throws Exception {
// 获取对象的所有方法
Method[] methods = object.getClass().getMethods();
for (Method method : methods) {
// 检查方法上是否有 @LogExecutionTime 注解
if (method.isAnnotationPresent(LogExecutionTime.class)) {
long startTime = System.currentTimeMillis();
// 执行方法
method.invoke(object);
long endTime = System.currentTimeMillis();
System.out.println("Execution time of " + method.getName() + ": " + (endTime - startTime) + " ms");
}
}
}
}
4. 测试
在 main 方法中,我们创建 MyService 对象并使用注解处理器来记录方法执行时间:
public class Main {
public static void main(String[] args) throws Exception {
MyService myService = new MyService();
LogExecutionTimeProcessor.process(myService);
}
}
5. 结果
程序运行后,输出类似以下内容:
Execution time of processData: 1001 ms
这就实现了通过自定义注解来记录方法的执行时间。注解的真正威力在于,它能够让我们的代码更加简洁,并且通过注解处理器灵活地控制行为。
五、注解的高级应用:Spring 和 Hibernate
在框架中,注解的使用已经达到极致,尤其是 Spring 和 Hibernate 这样的框架,它们几乎所有的功能都依赖于注解进行配置。比如:
-
Spring 注解:
@Autowired、@Component、@Service、@RequestMapping等,Spring 容器通过这些注解来进行自动化装配和控制反转(IoC)。 -
Hibernate 注解:
@Entity、@Id、@Column等,Hibernate 使用这些注解来映射 Java 类与数据库表之间的关系。
这些框架的工作原理,实际上都是通过扫描这些注解并通过反射获取相关信息,最终动态生成代码执行操作。
六、总结
通过今天的讲解,我们已经从注解的基础用法到自定义注解的实战应用,都有了全面的了解。你会发现,注解不仅仅是一个简单的标记,它的设计原理和应用场景都充满了“魔力”,它能够大大简化开发中的许多复杂任务。
核心总结:
- 注解的作用:通过元数据来描述程序的结构或提供额外的信息,不直接影响程序的逻辑。
- 自定义注解的优势:通过反射机制,能够在运行时灵活地处理业务逻辑,提高程序的可扩展性和解耦性。
- 高级应用:注解在 Spring、Hibernate 等框架中得到广泛应用,真正体现了注解在代码中的“黑魔法”力量。注解(Annotation)原理与自定义注解实战:你不懂的注解背后究竟发生了什么?
… …
文末
好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。
… …
学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!
wished for you successed !!!
⭐️若喜欢我,就请关注我叭。
⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。
版权声明:本文由作者原创,转载请注明出处,谢谢支持!
- 点赞
- 收藏
- 关注作者
评论(0)