在写 Java 的时候,一看到注解就另我很兴奋,因为这代表可以让我少写很多代码,如 @Select(),那就不用在 Mapper.xml 去配 MyBatis 了。但是这些注解背后到底做了什么,我是不知道的。因此这篇文章就深入了解一下注解。
先放个结论:注解只是个标注/标签,啥也不做。我们所看到的“行为”其实都有人去识别这个注解然后做的。
注解是什么
想想我们在读文言文的时候,我们基本是通过注解去了解意思的。比如看到
上面的 (2), (3), (4) 就是注解,看到后我们就去课文背后去看是啥意思:
OK,现在我们懂了“先生不知何许人也,......”的意思了。
Java 注解
和上面同理呀,JVM 看到注解 @Autowired,@Override 等,就去看这些玩意是啥意思呗,看懂了再去执行某些操作喽。
Java 注解的背后
这个时候你可能会想:JVM 去拿着注解去查背后的意义应该是 JVM 的事,我们的职责应该是去定义注解的意义,那又是如何定义的呢?
非常简单的一个思路:扫一次 Java 文件,把标了注解的东西(变量、方法、类.....)都拿出来,放到一个可能类似于 HashMap 的地方,比如:
@Shadiao
public void you;
@Shuaige
public void me;
存成
{
'Shadiao': 说XXX是沙雕,
'Shuaige': 说YYY是帅哥
}
存好后,就类似于我们所看到课文后面的注解表了。每次执行的时候,Java 就会跟所这个表去做相关的事。
ByteBuddy
为了完成上面的任务,有一个库 ByteBuddy 专门是用来检测注解,然后给他们附上操作的,是一种字节码增强技术。
一般先新建注解
public @interface XXX {}
然后检测这个注解
ByteBuddy()
.subclass(xxx)
.method(ElementMatchers.isAnnotatedWith(XXX.class))
.intercept(MethodDelegation.to(XXX.class)
.make()
.load()
.getLoaded()
注意要用 @Retention(RetentionPolicy.RUNTIME)
最后
看这上面这一串代码是不是头疼?其实Java本身已经提供了很多内置的注解了,如我们最熟悉的 @Override
,当用别人的库的时候,一般别人也会提供很多注解,如 @Autowired
,@Select
等。一般来说并不需要我们自己去发明注解。
看完这篇文章,你只需要知道注解只是标签,使用 ByteBuddy 可以检测这些注解并附上自己想要的操作,当 Java 执行时看到注解后,会自动执行你之前附上的操作。最重要要记住的是,你可以忘掉怎么使用 ByteBuddy,因为大部分时候都有人给你写好了,直接用注解即可。
网友评论