最近因爲系統可能要更換成java語言,於是每天都在拼命的研究java的相關知識和框架。之前學習註解的時候,沒有太深入的去理解它,只是覺得標註一下挺好用,但是現在在學到spring aop的時候,突然發現註解的功能是如此強大。不得已,只好仔細來研究一下註解的原理性問題了。
首先,網上有各種介紹註解是運用反射機制,但是我相信很多人其實並不熟練運用反射,當然我這個菜鳥更是如此。但好在反射雖並不常用,但是很好理解。而註解就顯得繞口很多。
言歸正傳,現在開始用我那白的不能再白的大白話跟大家講解一下了(畢竟這個行業總是喜歡搞一些裝逼的高大上的詞彙)。
爲了更好的向大家解釋,我還是先貼代碼吧(大家直接copy到自己的IDE上去跑就好)。
BusinessLogic.java
package 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的結果。大家感受一下就好