添加組織名java
選擇webweb
輸入項目名稱spring
建立後目錄結構爲app
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
加入自定義註解須要的註釋函數
@Documented //註解代表製做javadoc時,是否將註解信息加入文檔。若是註解在聲明時使用了@Documented,則在製做javadoc時註解信息會加入javadoc。spring-boot
@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) ///包spa
@Retention(RetentionPolicy.SOURCE) —— 這種類型的Annotations只在源代碼級別保留,編譯時就會被忽略.net
@Retention(RetentionPolicy.CLASS) —— 這種類型的Annotations編譯時被保留,在class文件中存在,但JVM將會忽略
@Retention(RetentionPolicy.RUNTIME) —— 這種類型的Annotations將被JVM保留,因此他們能在運行時被JVM或其餘使用反射機制的代碼所讀取和使用.3d
package vip.oldboy; import java.lang.annotation.*; /** * Created by peng on 18/6/29. */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface OldBoy { }
@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