1、什么是java注解?
定義:注解(Annotation),也稱之為元資料,是一種代碼級別的說明,是JDK1.5及以后版本引入的一個特性,與類、介面、列舉是在同一個層次,它可以宣告在包、類、欄位、方法、區域變數、方法引數等的前面,用來對這些元素進行說明,注釋,
作用分類:
- 1、撰寫檔案:通過代碼里標識的注解生成檔案
- 2、代碼分析:通過代碼里標識的注解對代碼進行分析
- 3、編譯檢查:通過代碼里標識的注解讓編譯器能夠實作基本的編譯檢查
2、JDK中的注解
JDK中的主鍵比較多,下面列舉一些進行說明
@Override:檢查被該注解注釋的是否是繼承自父類
@Deprecated:表示被注釋的內容已經過時,不過還可以用
@SuppressWarnings:壓制警告
@SuppressWarnings,壓制警告屬性:
- all to suppress all warnings (抑制所有警告)
- boxing to suppress warnings relative to boxing/unboxing operations(抑制裝箱、拆箱
操作時候的警告) - cast to suppress warnings relative to cast operations (抑制映射相關的警告)
- dep-ann to suppress warnings relative to deprecated annotation(抑制啟用注釋的警
告) - deprecation to suppress warnings relative to deprecation(抑制過期方法警告)
- fallthrough to suppress warnings relative to missing breaks in switch
statements(抑制確在switch中缺失breaks的警告) - finally to suppress warnings relative to finally block that don’t return (抑制
finally模塊沒有回傳的警告) - hiding to suppress warnings relative to locals that hide variable()
- incomplete-switch to suppress warnings relative to missing entries in a switch
statement (enum case)(忽略沒有完整的switch陳述句) - nls to suppress warnings relative to non-nls string literals(忽略非nls格式的字符)
- null to suppress warnings relative to null analysis(忽略對null的操作)
- rawtypes to suppress warnings relative to un-specific types when using generics
on class params(使用generics時忽略沒有指定相應的型別) - restriction to suppress warnings relative to usage of discouraged or forbidden
references - serial to suppress warnings relative to missing serialVersionUID field for a
serializable class(忽略在serializable類中沒有宣告serialVersionUID變數) - static-access to suppress warnings relative to incorrect static access(抑制不正
確的靜態訪問方式警告) - synthetic-access to suppress warnings relative to unoptimized access from inner
classes(抑制子類沒有按最優方法訪問內部類的警告) - unchecked to suppress warnings relative to unchecked operations(抑制沒有進行型別檢
查操作的警告) - unqualified-field-access to suppress warnings relative to field access
unqualified (抑制沒有權限訪問的域的警告) - unused to suppress warnings relative to unused code (抑制沒被使用過的代碼的警告)
@SuppressWarnings("all")
public class AnnotaionSimpleExample {
/**
* 介面過時,注釋,不過還是可以使用的
* @Param []
* @return void
*/
@Deprecated
public void v1() {
}
/**
* 新版介面,推薦用戶使用
* @Param []
* @return void
*/
public void v2(){}
@Override
public String toString() {
return super.toString();
}
}
3、自定義注解
語法:
public @interface [主鍵類名稱] { }
注解本質,自定義注解被反編譯后的內容,所以主鍵的本質就是實作了java.lang.annotation.Annotation這個父類的介面,所以注解本質就是一個介面
public interface MyAnnotaion extends java.lang.annotation.Annotation {
}
注解注意事項:
- 方法不應有任何 throws 子句
- 方法應回傳以下:基本資料型別、String型別、列舉型別、注解或者是這些型別的陣列
- 方法不應有任何引數
- 在 interface 關鍵字之前附加 @ 來定義注釋
- 可以使用
default關鍵字為該方法分配一個默認值,回傳值如果是陣列,default后面加上{}
public @interface MyAnnotation {
int value1() default 1;
String value2() default "";
String value3() default "str";
int[] intarr() default {1,2,3,4,5,6};
}
4、元注解
JDK中提供了4個元注解,在自定義注解時候經常需要用到
- 1、
@Target:描述當前注解能夠作用的位置- ElementType.TYPE:作用在類上
- ElementType.METHOD:作用在方法上
- ElementType.FIELD:作用在成員變數上
- 2、
@Retention:描述注解被保留到的階段- SOURCE:表示當前注解只有在代碼階段有效,編譯期間丟棄
- CLASS:該注解會被保留到位元組碼階段,指.class檔案,提供給java編譯器而不是JVM,包含在class檔案
- RUNTIME:該注解會被保留到運行階段 JVM,指的是運行時,可供 java 編譯器和 JVM 使用
- SOURCE < CLASS < RUNTIME
- 3、
@Documented:描述注解是否被抽取到JavaDoc api - 4、
@Inherited:描述注解是否可以被子類繼承
import java.lang.annotation.*;
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotation {
int value1() default 1;
}
5、自定義注解案例
下面通過一個例子,加上Spring AOP實作日志列印,加上這個自定義注釋的方法都會被攔截,然后獲取引數列印日志
自定義注解類:作用于方法
import java.lang.annotation.*;
/**
* <pre>
* 日志記錄注解類
* </pre>
*
* <pre>
* @author mazq
* 修改記錄
* 修改后版本: 修改人: 修改日期: 2021/08/11 09:32 修改內容:
* </pre>
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface EnableLogger {
}
pom加上spring-boot-starter-web和spring-boot-starter-aop
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
日志列印Aspect類:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
/**
* <pre>
* 日志列印Aspect類
* </pre>
*
* <pre>
* @author mazq
* 修改記錄
* 修改后版本: 修改人: 修改日期: 2021/08/11 09:42 修改內容:
* </pre>
*/
@Aspect
@Component
@EnableAspectJAutoProxy
public class LoggerAspect {
private Logger LOG = LoggerFactory.getLogger(LoggerAspect.class);
@Pointcut("@annotation(com.example.core.example.annotation.EnableLogger)")
public void pointCutMethod(){}
@Around("pointCutMethod()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
if (LOG.isInfoEnabled()) {
LOG.info(
"#method: {} ,args: {} , result:{}, used: {} ms",
MethodSignature.class.cast(joinPoint.getSignature()).getMethod().getName(),
joinPoint.getArgs(),
result,
System.currentTimeMillis() - start);
}
return result;
}
}
用戶資訊物體類:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import java.io.Serializable;
/**
* <pre>
* 用戶資訊物體類
*
*
* <pre>
* 修改記錄
* 修改后版本: 修改人: 修改日期: 2020/07/20 10:14 修改內容:
* </pre>
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class GithubUser implements Serializable {
private String name;
private String blog;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", blog='" + blog + '\'' +
'}';
}
}
RESTFul API測驗:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* <pre>
* 測驗控制類
* </pre>
*
* <pre>
* @author mazq
* 修改記錄
* 修改后版本: 修改人: 修改日期: 2021/08/11 10:03 修改內容:
* </pre>
*/
@RestController
public class HelloController {
private Logger LOG = LoggerFactory.getLogger(HelloController.class);
private final RestTemplate restTemplate;
public HelloController(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
}
/**
* <pre>獲取github用戶資訊 RESTFUL API </pre>
* {@link ://127.0.0.1:8080/api/hello/mojombo}
* @Author mazq
* @Date 2021/08/11 10:11
* @Param [userCode]
* @return org.springframework.http.ResponseEntity<?>
*/
@EnableLogger
@RequestMapping(value = {"/api/hello/{userCode}"})
public ResponseEntity<?> hello(@PathVariable("userCode") String userCode) {
LOG.info("Looking up " + userCode);
String url = String.format("https://api.github.com/users/%s", userCode);
GithubUser userInfo = restTemplate.getForObject(url, GithubUser.class);
return ResponseEntity.ok(userInfo);
}
}
在linux里呼叫介面:
curl http://127.0.0.1:8080/api/hello/mojombo
回傳json:
{
"name": "Tom Preston-Werner",
"blog": "http://tom.preston-werner.com"
}
被Spring AOP攔截,實作日志列印
#method: hello ,args: [mojombo] , result:<200 OK OK,User{name=‘Tom Preston-Werner’, blog=‘http://tom.preston-werner.com’},[]>, used: 1791 ms
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/293599.html
標籤:java
