AOP中獲取自定義注解的參數值


 

 

目錄

一、利用注解實現AOP的基本流程

  1.1、創建一個注解,用來注解切點(pointcut)

  1.2、創建一個service,使用上面定義的注解來指定切點

  1.3、創建Aspect,增加業務邏輯

  1.4、創建Spring配置類

  1.5、測試

二、獲取自定義注解的參數

  2.1、創建帶屬性的自定義注解

  2.2、創建service使用帶屬性的自定義注解

  2.3、創建Aspect的錯誤示例

  2.4、創建Aspect的正確做法

  2.5、測試

三、總結

 

 

一、利用注解實現AOP的基本流程 

  如果特別熟悉自定義注解實現AOP,可以直接轉到第二部分:跳轉

  Spring中,可以通過自定義注解的方式來實現AOP,比較簡單,流程如下:  

  1.1、創建一個注解,用來注解切點(pointcut)

1
2
3
4
5
6
7
8
9
10
11
12
package  cn.ganlixin.annotation;
 
import  java.lang.annotation.ElementType;
import  java.lang.annotation.Retention;
import  java.lang.annotation.RetentionPolicy;
import  java.lang.annotation.Target;
 
@Retention (RetentionPolicy.RUNTIME)
@Target (ElementType.METHOD)
public  @interface  DemoAnnotation {
     //注意這里沒有定義屬性
}

  

  1.2、創建一個service,使用上面定義的注解來指定切點

  這里為了節約篇幅,就不創建service接口,再創建serviceImpl來實現接口了,直接寫在service中:

1
2
3
4
5
6
7
8
9
10
11
12
13
package  cn.ganlixin.service;
 
import  cn.ganlixin.annotation.DemoAnnotation;
import  org.springframework.stereotype.Service;
 
@Service
public  class  DemoService {
 
     @DemoAnnotation   // 使用自定義的注解,聲明該方法為切點方法
     public  void  demo() {
         System.out.println( "this is DemoService.demo()" );
     }
}

  

  1.3、創建Aspect,增加業務邏輯

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package  cn.ganlixin.aspect;
 
import  org.aspectj.lang.annotation.Aspect;
import  org.aspectj.lang.annotation.Before;
import  org.springframework.stereotype.Component;
 
@Component
@Aspect
public  class  DemoAspect {
 
     @Before ( "@annotation(cn.ganlixin.annotation.DemoAnnotation)" )
     public  void  demoBefore() {
         System.out.println( "this is before output message" );
     }
}

  

  1.4、創建Spring配置類

  主要做的是:指定包掃描路徑

1
2
3
4
5
6
7
8
9
10
11
12
package  cn.ganlixin;
 
import  org.springframework.context.annotation.ComponentScan;
import  org.springframework.context.annotation.Configuration;
import  org.springframework.context.annotation.EnableAspectJAutoProxy;
 
@Configuration
@ComponentScan ( "cn.ganlixin" )
@EnableAspectJAutoProxy
public  class  AppConfig {
     
}

  

  1.5、測試

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package  cn.ganlixin;
 
import  cn.ganlixin.service.DemoService;
import  org.junit.Test;
import  org.springframework.context.ApplicationContext;
import  org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
public  class  AppTest {
 
     @Test
     public  void  testAOP1() {
         ApplicationContext context =  new  AnnotationConfigApplicationContext(AppConfig. class );
 
         DemoService demoService = context.getBean(DemoService. class );
         demoService.demo();
     }
}

  輸出:

1
2
this  is before output message
this  is DemoService.demo()

  

二、獲取自定義注解的參數

  2.1、創建帶屬性的自定義注解

  要獲取自定義注解參數,就需要在自定義注解中增加幾個屬性,下面自定義的TestAnnotation中有兩個屬性:value和description。

1
2
3
4
5
6
7
8
9
10
11
12
13
package  cn.ganlixin.annotation;
 
import  java.lang.annotation.ElementType;
import  java.lang.annotation.Retention;
import  java.lang.annotation.RetentionPolicy;
import  java.lang.annotation.Target;
 
@Retention (RetentionPolicy.RUNTIME)
@Target (ElementType.METHOD)
public  @interface  TestAnnotation {
     String value();
     String description()  default  "default description" ;
}

  

  2.2、創建service使用帶屬性的自定義注解

  service中有兩個方法,分別使用了自定義注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package  cn.ganlixin.service;
 
import  cn.ganlixin.annotation.TestAnnotation;
import  org.springframework.stereotype.Service;
 
@Service
public  class  TestService {
     
     @TestAnnotation ( "this is value" )
     public  void  test1() {
         System.out.println( "this is TestService.test1()" );
     }
     
     @TestAnnotation (value =  "this is another value" , description =  "this is description" )
     public  void  test2() {
         System.out.println( "this is TestService.test2()" );
     }
}

  

  2.3、創建Aspect的錯誤示例

  在寫博客之前,我也搜過相關的博客,但是發現很多博客中寫的都是利用@Around來實現獲取注解信息,但是我如果需要在@Before中,@After中獲取又怎么辦呢?雖然可以通過以下騷操作,通過@Around來模擬@Before和@After,但是還是感覺不好。

  下面還是使用@Before來實現的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package  cn.ganlixin.aspect;
 
import  cn.ganlixin.annotation.TestAnnotation;
import  org.aspectj.lang.annotation.Aspect;
import  org.aspectj.lang.annotation.Before;
import  org.springframework.stereotype.Component;
 
@Component
@Aspect
public  class  TestAspect {
 
     @Before ( "@annotation(cn.ganlixin.annotation.TestAnnotation)" )
     public  void  one(TestAnnotation testAnonotation) {
         System.out.println(testAnonotation.value());
         System.out.println(testAnonotation.description());
     }
}

  上面的代碼看似沒有問題,one()方法中接收一個TestAnnotation的參數,以為能夠獲取到切點方法的注解信息,但是,IDE會告訴你如下錯誤:

  

 

  2.4、創建Aspect的正確做法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package  cn.ganlixin.aspect;
 
import  cn.ganlixin.annotation.TestAnnotation;
import  org.aspectj.lang.annotation.Aspect;
import  org.aspectj.lang.annotation.Before;
import  org.aspectj.lang.annotation.Pointcut;
import  org.springframework.stereotype.Component;
 
@Component
@Aspect
public  class  TestAspect {
 
     // 先創建一個方法,方法名隨意,但是需要制定@annotation為剛剛自定義的注解
     @Pointcut ( "@annotation(cn.ganlixin.annotation.TestAnnotation)" )
     public  void  test() {}
 
     // 使用@Before,需要先引入上面@Pointcut注解的方法名,在加上@annotation,
     // @annotation中的值,需要和action方法中的參數名稱相同(必須相同,但是名稱任意)
     @Before ( "test() && @annotation(testAnnotation)" )
     public  void  action(TestAnnotation testAnnotation) {
         System.out.println( "Annotation value : "  + testAnnotation.value());
         System.out.println( "Annotation description : "  + testAnnotation.description());
         System.out.println( "this is TestAspect.action()" );
     }
}

  划重點:

1
2
3
4
5
6
7
// 第2個示例,強調@annotation中的值,需要和方法參數名相同
@Before ( "test() && @annotation(abcdef)" )
public  void  action2(TestAnnotation abcdef) {
     System.out.println( "Annotation value : "  + abcdef.value());
     System.out.println( "Annotation description : "  + abcdef.description());
     System.out.println( "this is TestAspect.action()" );
}

  

   2.5、測試

  Spring的配置類不用更改,測試代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package  cn.ganlixin;
 
import  cn.ganlixin.service.TestService;
import  org.junit.Test;
import  org.springframework.context.ApplicationContext;
import  org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
public  class  AppTest {
     @Test
     public  void  testAOP2() {
         ApplicationContext context =  new  AnnotationConfigApplicationContext(AppConfig. class );
         TestService testService = context.getBean(TestService. class );
         
         testService.test1();
         System.out.println( "----------------------------" );
         testService.test2();
     }
}

  輸出:

1
2
3
4
5
6
7
8
9
Annotation value :  this  is value
Annotation description :  default  description
this  is TestAspect.action()
this  is TestService.test1()
----------------------------
Annotation value :  this  is another value
Annotation description :  this  is description
this  is TestAspect.action()
this  is TestService.test2()

  

三、總結

  要想是獲取AOP中自定義注解的參數值,主要就一點:

  

 

如需轉載,請注明文章出處,謝謝!!!
 
分類:  Spring


免責聲明!

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



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