最近因为系统可能要更换成java语言,于是每天都在拼命的研究java的相关知识和框架。之前学习注解的时候,没有太深入的去理解它,只是觉得标注一下挺好用,但是现在在学到spring aop的时候,突然发现注解的功能是如此强大。不得已,只好仔细来研究一下注解的原理性问题了。
首先,网上有各种介绍注解是运用反射机制,但是我相信很多人其实并不熟练运用反射,当然我这个菜鸟更是如此。但好在反射虽并不常用,但是很好理解。而注解就显得绕口很多。
言归正传,现在开始用我那白的不能再白的大白话跟大家讲解一下了(毕竟这个行业总是喜欢搞一些装逼的高大上的词汇)。
为了更好的向大家解释,我还是先贴代码吧(大家直接copy到自己的IDE上去跑就好)。BusinessLogic.javapackage annotationTest;
/** * @author kalson
* @date 创建时间:2017年11月7日 下午1:13:14
* @version 1.0
*/
public class BusinessLogic {
public BusinessLogic() {
super();
}
public void compltedMethod() {
System.out.println("This method is complete");
}
@Todo(priority = Todo.Priority.HIGH)
public void notYetStartedMethod() {
// No Code Written yet
}
@Todo(priority = Todo.Priority.MEDIUM, author = "Uday", status = Todo.Status.STARTED)
public void incompleteMethod1() {
//Some business logic is written
//But its not complete yet
}
@Todo(priority = Todo.Priority.LOW, status = Todo.Status.STARTED )
public void incompleteMethod2() {
//Some business logic is written
//But its not complete yet
}
}
Todo
package annotationTest;
/** * @author kalson
* @date 创建时间:2017年11月7日 下午1:12:57
* @version 1.0
*/
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Todo {
public enum Priority {LOW, MEDIUM, HIGH}
public enum Status {STARTED, NOT_STARTED}
String author() default "Yash";
Priority priority() default Priority.LOW;
Status status() default Status.NOT_STARTED;
}
TodoReport
package annotationTest;
/** * @author kalson
* @date 创建时间:2017年11月7日 下午1:13:27
* @version 1.0
*/
import java.lang.reflect.Method;
public class TodoReport {
public TodoReport() {
super();
}
public static void main(String[] args) {
getTodoReportForBusinessLogic();
}
/**
* This method iterates through all messages of BusinessLogic class and fetches annotations defined on each of them.
* After that it displays the information from annotation accordingly.
*/
private static void getTodoReportForBusinessLogic() {
Class businessLogicClass = BusinessLogic.class;
for(Method method : businessLogicClass.getMethods()) {
Todo todoAnnotation = (Todo)method.getAnnotation(Todo.class);
if(todoAnnotation != null) {
System.out.println(" Method Name : " + method.getName());
System.out.println(" Author : " + todoAnnotation.author());
System.out.println(" Priority : " + todoAnnotation.priority());
System.out.println(" Status : " + todoAnnotation.status());
System.out.println(" --------------------------- ");
}
}
}
}
创建了三个类,一个BusinessLogic.java,要被注解的类
一个Todo.java,注解类
一个TodoReport ,测试类。
注解机制最终要的运用了反射机制就是由于如下代码部分Class businessLogicClass = BusinessLogic.class;
这个Class 的运用想必大家见过但是并没有认真理解过。所谓的类的类创建,说起来比较拗口,但是我举一个不恰当的例子。
理念一:假设把克隆当作java中new实例对象的过程,那么这个模型就是我们自己创建的类,但是克隆的原型其实并不是最底层,底层而是细胞,所以如果你想new一个对象,那你就需要先把这个模型new出来,而注解就是作用在这个过程,也就是说,JVM识别注解是在创建模型类的时候就开始识别了。
理念二:其次,需要再跟大家解释的一个问题就是,套用网上内容Annotations仅仅是元数据,和业务逻辑无关。所以,如果你在学习AOP等各种框架的时候,时刻想着,它的逻辑部分都是框架来实现的,暴露给用户的都只是一些标志点而已。至于逻辑部分,只好大家发挥脑洞,自己去猜测了。
==========================================================================================
有了上面两点理念之后,现在我们再来看一下一个用到spring框架的例子。@Aspect --说明这是一个切面类
public class Logging {
@Pointcut("execution(* com.yiibai.*.*(..))")//比如说这个注解,
JVM启动开始创建各种类的类对象的时候,就会识别到这个注解,它的逻辑是什么样的,由
spring框架来指定(比如说是对com.yiibai.下的所有类的所有方法都用selectAll做标记)。
private void selectAll() {
}
//@Before("@annotation(com.yiibai.Loggable)")
@Before("selectAll()")//比如说识别到Before这个注解的时候,会对selectAll标记的方法前绑定
beforeAdvice方法。这也是由spring框架来做的,所以我们看不到。
public void beforeAdvice() {
System.out.println("going to setup student profile");
}
@After("selectAll()")
public void afterAdvice() {
System.out.println("Student profile has been setup.");
}
//@AfterReturning("selectAll()")
public void afterReturningAdvice(Object retval) {
System.out.println("returing" + retval.toString());
}
//@AfterThrowing("selectAll()")
public void afterThrowingAdvice(IllegalArgumentException ex) {
System.out.println("There has been an exception: " + ex.toString());
}
}
由于目前只是学习阶段,还没有做对框架的底层研究,所以以上的观念纯属个人对这方面的抽象理解,希望大家能够结合自己的知识指正或者希望可以帮助大家理解注解。至于以上注释中的逻辑,也纯属个人yy的结果。大家感受一下就好