JAVA
元注解
- @Documented
- @Inherited
- @Retention
- @Target
- @Repeatable
- @Native
在java.lang.annotation包下,除了@Native之外都為元注解
元注解:是一種基礎注解(根注解),可以注解其他的注解上,
作用:用來解釋說明其他的注解,
@Documented
- 原始碼:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
- 說明:
? Document:檔案,被標注的注解用在類A上后類A的注解資訊可以被例如javadoc此類的工具檔案化,相關的注解資訊會出現在Doc中
@Inherited
-
原始碼:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Inherited { } -
說明:
Inherited:動詞,被繼承,被@Inherited注解標注的注解去注解了一個類后,凡是該類的子類均繼承注解被標注的注解
-
示例:
/** 被@Inherited注解標注的注解MySelf去注解了類Human后,類Human的子類Man繼承注解MySelf **/ @Inherited @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @Interface MySelf{ } @MySelf public class Human{} public class Man extends Human{}
@Retention
-
原始碼:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { RetentionPolicy value(); } -
說明:
Retention:保留期,存活期,解釋說明了被標注的注解的存活時間,
RetentionPolicy
SOURCE---------------------注解只保留在源檔案,當Java檔案編譯成class檔案的時候,注解被丟棄
CLASS------------------------默認值,注解被寫入位元組碼檔案,但jvm加載class檔案時候被丟棄
RUNTIME-------------------表明注解會被寫入位元組碼檔案,jvm運行時能夠獲取到,通過反射可以決議到
一般如果需要在運行時去動態獲取注解資訊,那只能用 RUNTIME 注解
如果要在編譯時進行一些預處理操作,比如生成一些輔助代碼(如 ButterKnife),就用 CLASS注解
如果只是做一些檢查性的操作,比如 @Override 和 @SuppressWarnings,則可選用 SOURCE 注解
@Target
-
原始碼:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType[] value(); } -
說明:
target:目標,物件,描述被修飾的注解的使用范圍,可以用在什么地方
ElementType
TYPE----------介面、類、列舉、注解
FIELD--------------欄位、列舉的常量
METHOD----------------方法
PARAMETER------------------方法引數
CONSTRUCTOR-------------------建構式
LOCAL_VARIABLE----------------------區域變數
ANNOTATION_TYPE------------------------注解
PACKAGE-------------------------------------------包
TYPE_PARAMETER-----------------------------------型別引數
TYPE_USE------------------------------------------------------任意型別(不包括class)
@Repeatable
-
原始碼:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Repeatable { Class<? extends Annotation> value(); } -
說明:
repeatabled:可重復,允許注解的重復使用,如:@ComponentScan
-
示例:
spring中示例:Scheduled
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Human { Man[] value(); } @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented @Repeatable(Human.class) public @interface Man { String name; } @Man("will") @Man("Jacky") public void test(){ }
@Native
- 原始碼:
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface Native {
}
-
說明:
指示定義常量值的欄位可以從本機代碼參考,
內置注解
@Deprecated
-
原始碼
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.METHOD, ElementType.PACKAGE, ElementType.PARAMETER, ElementType.TYPE}) public @interface Deprecated { } -
說明:
Deprecated:強烈反對,標記一個方法、變數、包等已經過時,再使用被標記的方法等會報編譯警告
-
示例:
public class Man(){
@Deprecated
public void getName(){}}
Man man = new Man();
man.getName();
@Override
-
原始碼:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { } -
說明:
override:推翻重寫,僅用在方法上,對該類所繼承的父類方法進行重寫
@SafeVarargs
-
原始碼:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.CONSTRUCTOR, ElementType.METHOD}) public @interface SafeVarargs {} -
說明:
safe varargs:安全的可變引數,宣告了可變引數的建構式或方法,會讓java編譯器報unchecked警告,如果程式員斷定該方法的主體不會對可變引數執行潛在的不安全的操作,可以使用@SafeVarargs來去除警告,說白了就是防止安全警告帶來的編譯錯誤,
可以用于建構式和static、final宣告的方法
-
示例:
public class Man(){ @SafeVarargs public Man(Object... val){} @SafeVarargs public static<T> void getName(T... tVal){} @SafeVarargs public final void getAge(String... val){} /**--------------Wrong------------ @SafeVarargs is not allowed on methods with fixed arity @SafeVarargs不允許在具有固定值的方法上使用 **/ @SafeVarargs public void getAge(String. tVal){} }
@SuppressWarnings
-
原始碼:
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); } -
說明:
suppress warning:抑制警告,對被注解的作用域內部的警告保持靜默,抑制警告的發生,value引數是抑制的警告型別, 詳見https://blog.csdn.net/lftaoyuan/article/details/104813851
@FunctionalInterface
-
原始碼:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface FunctionalInterface {} -
說明:
functional interface:函式式介面,功能介面,Java8新特性
特點:
- 有且僅有一個抽象方法
- 允許靜態方法
- 允許默認方法
- 允許java.lang.Object中public型別的方法,這些方法對于函式式介面來說,不被當成是抽象方法,因為所有的函式式介面的實作都是默認繼承了Object類,Object類含有該方法的實作,
- 該注解非必須,只要符合函式式介面的條件,可以不加注解,加上注解知識輔助編譯器進行檢查
Java的函式式介面有什么意義? - 知乎 (zhihu.com)
-
示例:
@FunctionalInterface interface Man{ // 抽象方法 void setName(String name); // 靜態方法 public static void getName(){ } // 默認方法 public default void setAge(){ } // java.lang.Object的public方法 public boolean equals(Object val); }
Spring(Boot)
宣告bean
? 宣告一個類為Spring的bean,可以被自動裝配,區別在于定位一個類的作用,由于企業級應用的開發注重分層,所以使用注解分別定義類的層次也可以更好地助力于開發,比使用xml進行配置更加簡單,
-
@Controller
-
@Service
-
@Repository
-
@Component
@Controller
-
原始碼:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Controller { @AliasFor( annotation = Component.class ) String value() default ""; } -
說明:
controller:控制者,控制器,對應MVC中的控制層
作用:接收用戶請求并呼叫不同的Service進行資料處理封裝,再將資料回傳給前端,配合視圖決議器可以回傳一個指定的頁面,而使用RestController則無法回傳指定頁面,但是可以回傳json
但是,@Controller僅說明這個類是一個控制器類,接收用戶請求需要@RequestMapping來映射一個Url讓用戶能夠通過該路徑訪問到
-
示例:
@Controller public class MyUser(){ @RequestMapping(value = "https://www.cnblogs.com/william-m/archive/2022/03/09/getName",method=RequestMethod.GET) public String getName(){ } } /** 呼叫getName方法: http:/localhost:8080/getName **/
@Service
-
原始碼:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Service { @AliasFor( annotation = Component.class ) String value() default ""; } -
說明:
service:服務,主要負責業務模塊的應用邏輯處理,呼叫Dao層介面從資料庫進行資料的獲取等操作
-
示例:
/** Service內的引數名字可以省略,默認為首字母小寫,示例為myUser **/ @Service("firstUser") public class MyUser(){ }
@Repository
-
原始碼:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Repository { @AliasFor( annotation = Component.class ) String value() default ""; } -
說明:
repository:倉庫,用于持久層介面,定義在dao層,
類似于@Mapper,但是使用@Repository并不常使用,單獨使用會報錯,需要增加其他配置,一般在啟動類添加@MapperScan("com.*.dao"),或者直接使用@Mapper注解
@Component
-
原始碼:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Indexed public @interface Component { String value() default ""; } -
說明:
component:組件,當一個類不屬于以上幾類又需要注入到bean時,使用@Component,是一個比較通用的定義bean的注解
注入bean
? 就是具體物件的創建,上一步的定義僅僅是定義,要具體的使用,一般可以用new,但是現在可以交給spring來創建,讓他去找到合適的物件給你,
- @Autowired
- @Inject(java)
- @Resource(java)
@Autowired
-
原始碼:
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { boolean required() default true; } -
說明:
? Autowired:自動裝配,可以對類成員建構式、方法、引數、變數、注解等進行標注,完成自動裝配的作業,省略getter、setter,
? 默認裝配方式:byType
? 在使用@Autowired時,在容器中查詢對應型別的bean
? 如果查詢結果只有一個,就將該bean裝配給@Autowired指定的資料
? 如果查詢的結果不止一個,可以配合@Qulifier("")根據名稱來查找,裝配方式:byName,或者在其中一個物件類添加@Primary注解,使用@Autowired時優先裝配該類
? 裝配程序:

-
示例:
/**1、作用在建構式 說明:@autowired寫在變數上的注入要等到類完全加載完,時間上晚于建構式,而且變數的加載也按照相應的順序 所以存在變數的加載要早于@autowired變數的加載的情況,這時@Autowired變數為null時進行了參考會報錯 --------ERROR------------------ @Service public class User{ @Autowired private final Man man; private String name; public User() { name = man.name();//man為null,報錯空指標 } } -------------------------------- **/ @Service public class User{ private final String name; @Autowired public User(Man man) { this.name= man.getName(); } } /**2、作用在普通方法上使用同1 會在注入的時候呼叫一次該方法,如果方法中有實參,會對方法里面的引數進行裝配,并呼叫一次該方法 可以用來做一些初始化操作 **/ @Service public class User{ private String name; @Autowired public void getUserName(Man man) { this.name= man.getName(); } } /**3、作用在引數上(非靜態方法的入參上) 用于初始化引數 示例效果同示例2 **/ @Service public class User{ private String name; public void getUserName(@Autowired Man man) { this.name= man.getName(); } } /** 4、作用在變數上 **/ @Autowired User user; /**5、作用在注解上 即自定義一個注解,然后在注解上添加@Autowired注解 實作注入功能的自定義注解名以及其他功能 **/注意事項:需要在類上加@Controller、@Service、@Component、@Repository等注解才能起作用
@Inject
-
原始碼:
package javax.inject; @Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Inject { } -
說明:
Inject:注射,用法與Autowired差不多,僅能在方法、構造方法和變數等,而且沒有required,
默認裝配方式:byType
配合@Named("bean名稱")完成根據name裝配
-
示例:
/**作用于變數**/ @Inject Man man; /**作用于方法**/ @Inject public void setName(Man man){ } @Inject @Named("自定義bean名稱") public void setName(Man man){ }
@Resource
-
原始碼:
package javax.annotation; @Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Resource { ... } -
說明:
resource:資源,
默認裝配方式:byName,根據定義可以知道還能通過byType進行注入
-
示例:
@Resource(name = "man") private Man man;
配置類
- @Configuration
- @Bean
- @EnableAutoConfiguration
- @ComponentScan
- @SpringBootApplication
@Configuration
-
原始碼:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Configuration { @AliasFor( annotation = Component.class ) String value() default ""; boolean proxyBeanMethods() default true; } -
說明:
configuration:配置,
用于定義一個配置類,初始化各項配置,比如:redis的Jackson2方式序列化,通常與@Bean結合使用,內部含有N>=0個被@Bean注解的方法,
注意事項:
1、該類不能為final型別
2、內部類只能為static靜態內部類
-
示例
@Configuration public class HuMan{ @Bean public Man getMan(){ Man man = new Man(); man.setSex(1); return man; } @Bean public Son getSon(){ // 若列印此時回傳的值和getMan()方法中回傳的值,應是兩個相同的物件 return getMan(); } }
@Bean
-
原始碼:
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Bean { ... } -
說明:
bean:豆子,JavaBean:物件,實體,
注解在方法上時,回傳一個bean交給容器,id為方法名,或者設定name引數
-
示例:
@Configuration public class HuMan{ //默認名字是getMan @Bean(name = "myMan") public Man getMan(){ Man man = new Man(); man.setSex(1); return man; } }
@EnableAutoConfiguration
-
原始碼:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { ... } -
說明:
EnableAutoConfiguration:允許自動配置,
將autoconfigure.jar/META-INF/spring.factories中EnableAutoConfiguration的值全部加載到容器,通常都是添加了@Configuration的類,目前集成在@SprinBootApplication注解中
@ComponentScan
-
原始碼:
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Repeatable(ComponentScans.class) public @interface ComponentScan { ... } -
說明:
componentScan:組件掃描,
設定可以被spring加載到容器的類(定義了bean的類),掃描添加了@Configuration的類,
相當于定義了bean之后,想去使用,前提是容器里邊有,所以需要spring掃描這些定義的bean裝配到容器,也是集成在@SpringBootApplication
@SpringBootApplication
-
原始碼:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) public @interface SpringBootApplication { ... } -
說明:
springboot應用,用于快捷配置一個啟動類,默認開啟自動裝配,掃描并加載bean
web
以下web的注解都在org.springframework.web.*下,僅記錄部分常用的
- @CrossOrigin
- @ResponseBody
- @RestController
- @RequestMapping
- @PathVariable
- @RequestParam
- @RequestBody
@CrossOrigin
-
原始碼:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CrossOrigin { ... } -
說明:
CrossOrigin:跨域,
瀏覽器的同源策略(有相同的協議,主機,埠號)限制,網站的訪問會拒絕跨域請求,比如:前后端分離專案的跨域問題,如果想要進行跨域的訪問,可以在類、方法上添加@CrossOrigin注解來允許跨域訪問
-
示例:
/** 1、寫在方法上 **/ /**沒有引數,允許類中所有的方法接收跨域請求**/ @CrossOrigin @Controller public class Man{ } /**origin引數,允許me跨域請求該類中的方法**/ @CrossOrigin(origin="http://me.com") @Controller public class Man{ } /** 2、寫在方法上,允許該跨域請求該方法 **/ @Controller public class Man{ @CrossOrigin @RequestMapping(...) public String getName(){...} }
@ResponseBody
-
原始碼:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ResponseBody { } -
說明:
response body:回應體,對應請求體,
用于將回傳的引數格式化為json型別,按照SpringMVC的運行流程,一個請求應該回傳的是一個視圖,通過視圖決議器后展現在web頁面,而添加@ResponseBody后可以將結果寫入到該net請求的response body中去,而不走試圖決議器
@RestController
-
原始碼:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Controller @ResponseBody public @interface RestController { @AliasFor( annotation = Controller.class ) String value() default ""; } -
說明:
@Restcontroller 集成了@Controller和@ResponseBody,可以以json的形式回傳資料給前端,如果回傳字串的話當然還是String型別,不會被json化,目前很多專案都是前后端分離的,所以對外的介面一般都用@RestController
@RequestMapping
-
原始碼:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Mapping public @interface RequestMapping { ... } -
說明:
request mapping:請求映射,
用于映射一個請求的路徑供外部請求的進入,可以作用于方法、類上,
-
示例:
/** 請求路徑為http://host:port/human-request/getName 如果類上不加該注解的話, 請求路徑為http://host:port/getName 一般都會在類上添加該注解,因為專案方法多了之后,請求路徑容易重復 **/ @RequestMapping("human-request") @RestController public class Human{ @RequestMapping("getName",method=Requestmethod.GET) public String getName(){ return ""; } } /** 可以與@Pathvariable注解一塊使用,可以在請求路徑上添加引數 傳入id為2,請求路徑為 http://host:port/getName/2 **/ @RestController public class Human{ @RequestMapping("getName/{id}",method=Requestmethod.GET) public String getName(@Pathvariable int id){ return ""; } } /** @RequestMapping("getName",method=Requestmethod.GET)==@GetMapping("getName") @RequestMapping("getName",method=Requestmethod.POST)==@PostMapping("getName") 同PutMapping,DeleteMapping,PatchMapping **/
@PathVariable
-
原始碼:
@Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface PathVariable { @AliasFor("name") String value() default ""; @AliasFor("value") String name() default ""; boolean required() default true; } -
說明:
path variable:路徑變數,
用于接收請求路徑中占位符的值,默認是必須傳入,可以傳入多個
-
示例:
/** 若傳入id為2 請求路徑為http://host:port/getName/2且路徑中的2必穿 **/ @RequestMapping("getName/{id}",method=RequestMethod.GET) public String getName(@PathVariable int id){ return ""; } /** 設定required=false時 若傳入id為2 請求路徑為http://host:port/getName/2,路徑中的2可以不傳 **/ @RequestMapping("getName/{id}",method=RequestMethod.GET) public String getName(@PathVariable(required=false) int id){ return ""; }
@RequestParam
-
原始碼:
@Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestParam { ... } -
說明:
request param:請求引數,
用于將引數賦給控制器方法中的形參上,默認引數必傳,可以傳遞多個,僅作用于引數,可以使用required=false
-
示例:
/** 請求路徑:http://host:port/getName?id=2 **/ @RequestMapping("getName", method=RequestMathod.GET) public String getName(@Requestparam Long id){ return ""; }
@RequestBody
-
原始碼:
@Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestBody { boolean required() default true; } -
說明:
request body:請求體
用于接收傳遞的json資料,前端傳遞json資料一般都用POST提交到請求體中用于后端接收,僅能有一個,
-
示例:
/** 請求路徑:http://host:port/getName 前端使用axios的話將json資料傳入data中 **/ @RequestMapping("getName", method=RequestMathod.POST) public String getName(@RequestBody Man man){ return ""; }
AOP
? AOP(Aspect Orient Programming) 面向切面編程,底層的實作就是采用動態代理模式實作的,采用了JDK的動態代理和CGLIB的動態代理,
-
@Aspect
-
@Before
-
@AfterReturning
-
@Around
-
@AfterThrowing
-
@After
-
@PointCut
@Aspect
-
原始碼:
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface Aspect { String value() default ""; } -
說明:
? Aspect:方面,切面,
? 標識一個類為切面類,用于給目標類增加一些功能
? 特點:一般都是非業務方法,獨立使用的AspectJ的相關注解,一般配合@Component使用,先將類加到spring容器,再使用@Aspect定義為切面類
@Before
-
原始碼:
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Before { String value(); String argNames() default ""; } -
說明:
屬性: value,是切入點運算式,表示切面的功能執行的位置, 位置: 在方法的上面 功能:前置通知,在目標方法之前執行 特點: 1.在目標方法之前先執行的 2.不會改變目標方法的執行結果 3.不會影響目標方法的執行, -
示例:
@Before(value="https://www.cnblogs.com/william-m/archive/2022/03/09/execution(public void com.will.HumanImpl.getName(id))") public void getNameBefore(){ // 需要執行的功能代碼 } /* * 指定通知方法中的引數:JoinPoint * JoinPoint:業務方法,要加入切面功能的業務方法 * 作用是:可以在通知方法中獲取方法執行時的資訊,例如方法名稱,方法的實參, * 如果你的切面 功能中需要用到方法的資訊,就加入JoinPoint. * 這個JoinPoint引數的值是由框架賦予,必須是第一個位置的引數 */ @Before(value="https://www.cnblogs.com/william-m/archive/2022/03/09/execution(public void com.will.HumanImpl.getName(id))") public void myBefore(JoinPoint jp){ //獲取方法的完整定義 system.out.println("方法的簽名(定義)="+jp.getsignature()); system.out.println("方法的名稱="+jp.getsignature().getName());//獲取方法的實參 object args []= jp.getArgs(); for (object arg:args){ system.out.println("引數="+arg); } }
@AfterReturning
-
原始碼:
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface AfterReturning { String value() default ""; String pointcut() default ""; String returning() default ""; String argNames() default ""; } -
說明:
后置通知定義方法,方法是實作切面功能的,
方法的定義要求:
? 1.公共方法 public
? 2.方法沒有回傳值
? 3.方法名稱自定義
? 4.方法有引數的,推薦是object,引數名自定義
**@AfterReturning:后置通知** 屬性: 1.value切入點運算式 2.returning自定義的變數,表示目標方法的回傳值的,自定義變數名必須和通知方法的形參名一樣, 位置:在方法定義的上面 特點: 1. 在目標方法之后執行的, 2. 能夠獲取到目標方法的回傳值,可以根據這個回傳值做不同的處理功能 3. 可以修改這個回傳值 -
示例:
@AfterReturning(value="https://www.cnblogs.com/william-m/archive/2022/03/09/execution(* *..SomeServiceImpl.doOther(..))",returning="res") // 此處returning的res名稱=Object的res名稱就行 public void myAfterReturing(object res){ // object res:是目標方法執行后的回傳值,根據回傳值做你的切面的功能處理 // 思考:如果是對類物件res的更改會不會影響在程式執行后得到的輸出結果? system.out.println("后置通知:在目標方法之后執行的,獲取的回傳值是:"+res); if(res.equals("abcd")) { //做―些功能 } e1se { //做其它功能 } }
@Around
-
原始碼:
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Around { String value(); String argNames() default ""; } -
說明:
環繞通知 方法的定義格式: 1.public 2.必須有一個回傳值,推薦使用object 3.方法名稱自定義 4.方法有引數,固定的引數ProceedingjoinPoint 等同于jdk動態代理的,InvocationHandler介面 引數:ProceedingJoinPoint 等同于Method 作用:執行目標方法 回傳值:就是目標方法的執行結果,可以被修改 -
示例:
@Around(value = "https://www.cnblogs.com/william-m/archive/2022/03/09/execution(* *..SomeService1mpl.doFirst(..))") public object myAround(ProceedingJoinPoint pjp) throws Throwable { // 獲取第一個引數值 Object[] args = pjp.getArgs(); String name = ""; if(args != null && args.length > 1){ Object arg = args[0]; name = (String)arg; } //實作環繞通知 object result = null; system.out.println("環繞通知:在目標方法之前,輸出時間:"+ new Date()); //1.目標方法呼叫 if("xxx".equals(name)){ // 控制是否執行目標方法 result = pjp.proceed(); //method.invoke(); object result = doFirst(); } system.out.println("環繞通知:在目標方法之后,提交事務"); //2.在目標方法的前或者后加入功能 //回傳目標方法的執行結果 return result; }
@AfterThrowing
-
原始碼:
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface AfterThrowing { String value() default ""; String pointcut() default ""; String throwing() default ""; String argNames() default ""; } -
說明:
方法的定義格式:
1、public
2、沒有回傳值
3、方法,名稱自定義
4、方法有一個Exception,如果還有就是JoinPoint
@AfterThrowing:例外通知 屬性: 1、value 2、throwing自定義變數,表示目標方法拋出的例外物件,變數名和方法的引數名一樣 特點: 1、在目標方法拋出例外時執行 2、可以做例外的監控程式,如果有例外,可以發郵件,短信通知等 執行時: 沒有例外就走正常邏輯,有例外就走定義的@AfterThrowing注解的方法try{ SomeServiceImpl.doSecond(..); } catch(Exception ex){ myAfterThrowing(ex); } -
示例:
@AfterThrowing(value = "https://www.cnblogs.com/william-m/archive/2022/03/09/execution(* *..SomeServiceImpl.doSecond(..))",throwing = "ex") public void myAfterThrowing(Exception ex){ system.out.println("例外通知:方法發生例外時,執行: "+ex.getMessage());//發送郵件,短信,通知開發人員 }
@ After
-
原始碼:
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface After { String value(); String argNames() default ""; } -
說明:
After:最終通知
方法的定義格式
? 1.public
? 2.沒有回傳值
? 3.方法名稱自定義
? 4.方法沒有引數,如果還有是JoinPoint
@After:最終通知 屬性:value 切入點運算式 位置:方法上面 特點: 1、總是執行 2、目標方法后執行,即使拋出了例外 類似于: try/catch中的finally代碼塊 -
示例:
@After(value = "https://www.cnblogs.com/william-m/archive/2022/03/09/execution(* *..SomeserviceImpl.doThird(..))") public loidmyAfter(){ //一般做資源清除作業的, systemyout.println("執行最終通知,總是會被執行的代碼"); }
@PointCut
-
原始碼:
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Pointcut { String value() default ""; String argNames() default ""; } -
說明:
定義管理切入點
如果專案中很多個切入點運算式是重復的,,使用@PointCut
屬性:value 切入點運算式 位置:方法上面 特點: 當使用@Pointcut定義在一個方法的上面,此時這個方法的名稱就是切入點運算式的別名,其它的通知中,value屬性就可以使用這個方法名稱,代替切入點運算式了 -
示例:
@Pointcut(value = "https://www.cnblogs.com/william-m/archive/2022/03/09/execution(* *..SomeserviceImpl.doThird(..))”) private void mypt(){ //無需代碼, } // 然后: @Before(value="mypt()") public void myBefore(){ }
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/440382.html
標籤:其他
