使用IDEA創建SpringBoot自定義注解


創建SpringBoot項目

添加組織名

選擇web

輸入項目名稱

 

創建后目錄結構為

使用Spring的AOP先加入Maven依賴

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

這里先創建一個自己定義的注解

加入自定義注解需要的注釋

@Documented  //注解表明制作javadoc時,是否將注解信息加入文檔。如果注解在聲明時使用了@Documented,則在制作javadoc時注解信息會加入javadoc。

@Target(ElementType.TYPE) //接口、類、枚舉、注解
@Target(ElementType.FIELD) //字段、枚舉的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法參數
@Target(ElementType.CONSTRUCTOR) //構造函數
@Target(ElementType.LOCAL_VARIABLE)//局部變量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包

 

 

@Retention(RetentionPolicy.SOURCE) —— 這種類型的Annotations只在源代碼級別保留,編譯時就會被忽略

@Retention(RetentionPolicy.CLASS) —— 這種類型的Annotations編譯時被保留,在class文件中存在,但JVM將會忽略
@Retention(RetentionPolicy.RUNTIME) —— 這種類型的Annotations將被JVM保留,所以他們能在運行時被JVM或其他使用反射機制的代碼所讀取和使用.

package vip.oldboy;

import java.lang.annotation.*;

/**
 * Created by peng on 18/6/29.
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OldBoy {

}

  

AOP配置

@Service用於標注業務層組件

@Controller用於標注控制層組件(如struts中的action)

@Repository用於標注數據訪問組件,即DAO組件

@Component泛指組件,當組件不好歸類的時候,我們可以使用這個注解進行標注。

@Aspect//切面

@Pointcut//定義需要切面的地方,表達式參數(https://blog.csdn.net/elim168/article/details/78150438)

@annotation//當執行的方法上擁有指定的注解時生效。

 

@After

@Before

@Around

就不用解釋了。

package vip.oldboy;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * Created by peng on 18/6/29.
 */
@Component
@Aspect
public class OldBoyAspect {

    @Pointcut("@annotation(vip.oldboy.OldBoy)")
    private void oldboy() { }

    /**
     * 定制一個環繞通知
     * @param joinPoint
     */
    @Around("oldboy()")
    public void advice(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Around Begin");
        joinPoint.proceed();//執行到這里開始走進來的方法體(必須聲明)
        System.out.println("Around End");
    }

    //當想獲得注解里面的屬性,可以直接注入改注解
    //方法可以帶參數,可以同時設置多個方法用&&
    @Before("oldboy()")
    public void record(JoinPoint joinPoint) {
        System.out.println("Before");
    }

    @After("oldboy()")
    public void after() {
        System.out.println("After");
    }
}

  

ProceedingJoinPoint和JoinPoint說明
AspectJ使用org.aspectj.lang.JoinPoint接口表示目標類連接點對象,如果是環繞增強時,使用org.aspectj.lang.ProceedingJoinPoint表示連接點對象,該類是JoinPoint的子接口。任何一個增強方法都可以通過將第一個入參聲明為JoinPoint訪問到連接點上下文的信息。我們先來了解一下這兩個接口的主要方法:

1.JoinPoint
 java.lang.Object[] getArgs():獲取連接點方法運行時的入參列表;
 Signature getSignature() :獲取連接點的方法簽名對象;
 java.lang.Object getTarget() :獲取連接點所在的目標對象;
 java.lang.Object getThis() :獲取代理對象本身;
2.ProceedingJoinPoint
ProceedingJoinPoint繼承JoinPoint子接口,它新增了兩個用於執行連接點方法的方法:
 java.lang.Object proceed() throws java.lang.Throwable:通過反射執行目標對象的連接點處的方法;
 java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通過反射執行目標對象連接點處的方法,不過使用新的入參替換原來的入參。

控制層

 

package vip.oldboy;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by peng on 18/6/29.
 */
@RestController
public class OldBoyController {
    @OldBoy
    @RequestMapping("/oldboy")
    public void getLog(){
        System.out.println("oldboy is coming");
    }
}

 

最后項目結構

 

啟動項目,訪問地址localhost:8080/oldboy

 

 

總結

Around最先執行

然后在執行proceed方法之前,Before先執行

然后才是方法體本身

然后是Around再結尾

最后才是After

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM