註解英文稱 Annotaion,是Java從1.5開始支持加入源碼的特殊語法元數據,做爲程序的元數據嵌入到程序當中。註解實現有一個重要的接口Annotation接口,利用@interface關鍵字,將全部使用該關鍵字的註解類都實現Annotation接口。Annontation像一種修飾符同樣,應用於包、類型、構造方法、方法、成員變量、參數及本地變量的聲明語句中。前端
使用註解的好處:java
一、幫助代碼編譯檢查web
二、提升代碼的識別度,好比 @override @Deprecated spring
三、減小重複代碼,簡化代碼apache
四、根據註解生成幫助文檔,如 @Decument 等app
基本語法:ide
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AnnotationName{ }
import java.lang.annotation.*; /** * 打印出操做日誌 * @author * @create 2019/11/4 */ //定義該註解的做用範圍 @Target({ElementType.TYPE, ElementType.METHOD}) //定義該註解的生命週期 @Retention(RetentionPolicy.RUNTIME) //註解將生成到javadoc中 @Documented public @interface SystemLog { /** * 日誌內容 * @return */ String message() default ""; }
注意:規定註解裏面只能使用java基本數據類型和String、enum、Annotation、classspa
1> 定義註解接口日誌
import java.lang.annotation.*; /** * 打印出操做日誌 * @author * @create 2019/11/4 */ //定義該註解的做用範圍 @Target({ElementType.TYPE, ElementType.METHOD}) //定義該註解的生命週期 @Retention(RetentionPolicy.RUNTIME) //註解將生成到javadoc中 @Documented public @interface SystemLog { /** * 日誌內容 * @return */ String message() default ""; }
2>實現接口,code
import com.example.shiro.config.SystemLog; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.lang.reflect.Method; /** * 日誌攔截 * @author * @create 2019/11/4 */ @Slf4j //使用order屬性,設置該類在spring容器中的加載順序 @Order(10) //做用是把當前類標識爲一個切面供容器讀取 @Aspect //把普通類實例化到spring容器中 @Component public class OuterServiceAop { @Pointcut("@annotation(com.example.shiro.config.SystemLog)") public void serviceAop(){} @Before("serviceAop()") public void doBefore(JoinPoint joinPoint) { log.info("前置通知"); } @After("serviceAop()") public void doAfter(JoinPoint joinPoint) { log.info("後置通知"); } @AfterReturning(pointcut = "serviceAop()", returning = "res") public void doAfterReturning(JoinPoint joinPoint, Object res) { log.info("日誌返回通知"); //請求方法 String method = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName(); log.info("method:"+ method); //日誌描述 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method1 = signature.getMethod(); SystemLog annotation = method1.getAnnotation(SystemLog.class); String message = annotation.message(); log.info(message); } @AfterThrowing(pointcut = "serviceAop()", throwing = "e") public void doAfterThrowing(JoinPoint joinPoint, Throwable e) { log.info("異常通知"); log.info("異常信息:" + e.getMessage()); } }
3>在須要的類或方法中增長註解
import com.example.shiro.config.SystemLog; import com.example.shiro.entity.User; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.example.shiro.common.BaseController; /** * <p> * 前端控制器 * </p> * * @author * @since 2019-11-01 */ @RestController @RequestMapping("/user") public class UserController extends BaseController { @PostMapping("/login") @SystemLog(message = "用戶登陸") public String login(User user) { ... } }
4>效果