中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用的Java 注解

發布時間:2021-10-23 17:16:41 來源:億速云 閱讀:118 作者:iii 欄目:編程語言

本篇內容主要講解“怎么使用的Java 注解”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么使用的Java 注解”吧!

Java 元注解

注解(Annotation)是一種可以放在 Java  類上,方法上,屬性上,參數前面的一種特殊的注釋,用來注釋注解的注解叫做元注解。元注解我們平常不會編寫,只需要添加到我們自己編寫的注解上即可,。

Java 自帶的常用的元注解有@Target,@Retention,@Documented,@Inherited 分別有如下含義

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. @Target:標記這個注解使用的地方,取值范圍在枚舉  java.lang.annotation.ElementType:TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE,TYPE_PARAMETER,TYPE_USE。

  3. @Retention :標識這個注解的生命周期,取值范圍在枚舉  java.lang.annotation.RetentionPolicy,SOURCE,CLASS,RUNTIME,一般定義的注解都是在運行時使用,所有要用  @Retention(RetentionPolicy.RUNTIME);

  4. @Documented:表示注解是否包含到文檔中。

  5. @Inherited  :使用@Inherited定義子類是否可繼承父類定義的Annotation。@Inherited僅針對@Target(ElementType.TYPE)類型的annotation有效,并且僅針對class的繼承,對interface的繼承無效。

定義注解

上面介紹了幾個元注解,下面我們定義一個日志注解來演示一下,我們通過定義一個名為OperationLog  的注解來記錄一些通用的操作日志,比如記錄什么時候什么人查詢的哪個表的數據或者新增了什么數據。編寫注解我們用的是 @interface  關鍵字,相關代碼如下:

package com.api.annotation;  import java.lang.annotation.*;  /**  * <br>  * <b>Function:</b><br>  * <b>Author:</b>@author 子悠<br>  * <b>Date:</b>2020-11-17 22:10<br>  * <b>Desc:</b>用于記錄操作日志<br>  */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface OperationLog {      /**      * 操作類型      *      * @return      */     String type() default OperationType.SELECT;      /**      * 操作說明      *      * @return      */     String desc() default "";      /**      * 請求路徑      *      * @return      */     String path() default "";      /**      * 是否記錄日志,默認是      *      * @return      */     boolean write() default true;      /**      * 是否需要登錄信息      *      * @return      */     boolean auth() default true;    /**      * 當 type 為 save 時必須      *      * @return      */     String primaryKey() default "";      /**      * 對應 service 的 Class      *      * @return      */     Class<?> defaultServiceClass() default Object.class; }

說明

上面的注解,我們增加了@Target({ElementType.METHOD}) ,  @Retention(RetentionPolicy.RUNTIME), @Documented  三個元注解,表示我們這個注解是使用在方法上的,并且生命周期是運行時,而且可以記錄到文檔中。然后我們可以看到定義注解采用的u是@interface  關鍵字,并且我們給這個注解定義了幾個屬性,同時設置了默認值。主要注意的是平時我們編寫的注解一般必須設置@Target和@Retention,而且  @Retention一般設置為RUNTIME,這是因為我們自定義的注解通常要求在運行期讀取,另外一般情況下,不必寫@Inherited。

使用

上面的動作只是把注解定義出來了,但是光光定義出來是沒有用的,必須有一個地方讀取解析,才能提現出注解的價值,我們就采用 Spring 的 AOP  攔截這個注解,將所有攜帶這個注解的方法所進行的操作都記錄下來。

package com.api.config;  import lombok.extern.slf4j.Slf4j; 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.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping;  import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.*;  /**  * <br>  * <b>Function:</b><br>  * <b>Author:</b>@author 子悠<br>  * <b>Date:</b>2020-11-17 14:40<br>  * <b>Desc:</b>aspect for operation log<br>  */ @Aspect @Component @Order(-5) @Slf4j public class LogAspect {     /**      * Pointcut for methods which need to record operate log      */     @Pointcut("within(com.xx.yy.controller..*) && @annotation(com.api.annotation.OperationLog)")     public void logAspect() {     }      /**      * record log for Admin and DSP      *      * @param joinPoint parameter      * @return result      * @throws Throwable      */     @Around("logAspect()")     public Object around(ProceedingJoinPoint joinPoint) throws Throwable {         Object proceed = null;         String classType = joinPoint.getTarget().getClass().getName();         Class<?> targetCls = Class.forName(classType);         MethodSignature ms = (MethodSignature) joinPoint.getSignature();         Method targetMethod = targetCls.getDeclaredMethod(ms.getName(), ms.getParameterTypes());         OperationLog operation = targetMethod.getAnnotation(OperationLog.class);         if (null != operation && operation.write()) {             SysMenuOpLogEntity opLogEntity = new SysMenuOpLogEntity();             StringBuilder change = new StringBuilder();             if (StrUtil.isNotBlank(operation.type())) {                 switch (operation.type()) {                     case OperationType.ADD:                         proceed = joinPoint.proceed();                         String addString = genAddData(targetCls, operation.defaultServiceClass(), joinPoint.getArgs());                         opLogEntity.setAfterJson(addString);                         change.append(OperationType.ADD);                         break;                     case OperationType.DELETE:                         String deleteString = autoQueryDeletedData(targetCls, operation.primaryKey(), operation.defaultServiceClass(), joinPoint.getArgs());                         opLogEntity.setBeforeJson(deleteString);                         change.append(OperationType.DELETE);                         proceed = joinPoint.proceed();                         break;                     case OperationType.EDIT:                         change.append(OperationType.EDIT);                         setOpLogEntity(opLogEntity, targetCls, operation.primaryKey(), operation.defaultServiceClass(), joinPoint.getArgs());                         proceed = joinPoint.proceed();                         break;                     case OperationType.SELECT:                         opLogEntity.setBeforeJson(getQueryString(targetCls, operation.defaultServiceClass(), joinPoint.getArgs()));                         change.append(operation.type());                         proceed = joinPoint.proceed();                         break;                     case OperationType.SAVE:                         savedDataOpLog(opLogEntity, targetCls, operation.primaryKey(), operation.defaultServiceClass(), joinPoint.getArgs());                         change.append(operation.type());                         proceed = joinPoint.proceed();                         break;                     case OperationType.EXPORT:                     case OperationType.DOWNLOAD:                         change.append(operation.type());                         proceed = joinPoint.proceed();                         break;                     default:                 }                 opLogEntity.setExecType(operation.type());             }             StringBuilder changing = new StringBuilder();             if (StrUtil.isNotBlank(opLogEntity.getExecType())) {                 if (operation.auth()) {                     LoginUserVO loginUser = getLoginUser();                     if (null != loginUser) {                         opLogEntity.setUserId(loginUser.getUserId());                         opLogEntity.setUserName(loginUser.getUserName());                         changing.append(loginUser.getUserName()).append("-");                     } else {                         log.error("用戶未登錄");                     }                 }                 opLogEntity.setCreateTime(DateUtils.getCurDate());                 opLogEntity.setRemark(getOperateMenuName(targetMethod, operation.desc()));                 opLogEntity.setPath(getPath(targetMethod, targetMethod.getName()));                 opLogEntity.setChanging(changing.append(change).toString());                 menuOpLogService.save(opLogEntity);             }         }         return proceed;     }      /**      * query data by userId      *      * @param targetCls           class      * @param defaultServiceClass default service class      * @return      * @throws Exception      */     private String queryByCurrentUserId(Class<?> targetCls, Class<?> defaultServiceClass) throws Exception {         BaseService baseService = getBaseService(targetCls, defaultServiceClass);         LoginUserVO loginUser = dspBaseService.getLoginUser();         if (null != loginUser) {             Object o = baseService.queryId(loginUser.getUserId());             return JsonUtils.obj2Json(o);         }         return null;     }      /**      * return query parameter      *      * @param targetCls           class      * @param args                parameter      * @param defaultServiceClass default service class      * @return      * @throws Exception      */     private String getQueryString(Class<?> targetCls, Class<?> defaultServiceClass, Object[] args) {         if (args.length > 0) {             Class<?> entityClz = getEntityClz(targetCls, defaultServiceClass);             for (Object arg : args) {                 if (arg.getClass().equals(entityClz) || arg instanceof BaseModel) {                     return JsonUtils.obj2Json(arg);                 }             }         }         return null;     }      /**      * save record log while OperatorType is SAVE      *      * @param opLogEntity         entity      * @param targetCls           class      * @param primaryKey          primaryKey      * @param defaultServiceClass default service class      * @param args                parameter      * @throws Exception      */     private void savedDataOpLog(SysMenuOpLogEntity opLogEntity, Class<?> targetCls, String primaryKey, Class<?> defaultServiceClass, Object[] args) throws Exception {         Class<?> entityClz = getEntityClz(targetCls, defaultServiceClass);         BaseService baseService = getBaseService(targetCls, defaultServiceClass);         for (Object arg : args) {             if (arg.getClass().equals(entityClz)) {                 if (StrUtil.isNotBlank(primaryKey)) {                     Field declaredField = entityClz.getDeclaredField(primaryKey);                     declaredField.setAccessible(true);                     Object primaryKeyValue = declaredField.get(arg);                     //if primary key is not null that means edit, otherwise is add                     if (null != primaryKeyValue) {                         //query data by primary key                         Object o = baseService.queryId(primaryKeyValue);                         opLogEntity.setBeforeJson(JsonUtils.obj2Json(o));                     }                 }                 opLogEntity.setAfterJson(JsonUtils.obj2Json(arg));             }         }     }      /**      * set parameter which edit data      *      * @param opLogEntity         entity      * @param targetCls           class      * @param primaryKey          primaryKey      * @param defaultServiceClass default service class      * @param args                parameter      * @throws Exception      */     private void setOpLogEntity(SysMenuOpLogEntity opLogEntity, Class<?> targetCls, String primaryKey, Class<?> defaultServiceClass, Object[] args) throws Exception {         Map<String, String> saveMap = autoQueryEditedData(targetCls, primaryKey, defaultServiceClass, args);         if (null != saveMap) {             if (saveMap.containsKey(ASPECT_LOG_OLD_DATA)) {                 opLogEntity.setBeforeJson(saveMap.get(ASPECT_LOG_OLD_DATA));             }             if (saveMap.containsKey(ASPECT_LOG_NEW_DATA)) {                 opLogEntity.setBeforeJson(saveMap.get(ASPECT_LOG_NEW_DATA));             }         }     }      /**      * query data for edit and after edit operate      *      * @param targetCls           class      * @param primaryKey          primaryKey      * @param defaultServiceClass default service class      * @param args                parameter      * @return map which data      * @throws Exception      */     private Map<String, String> autoQueryEditedData(Class<?> targetCls, String primaryKey, Class<?> defaultServiceClass, Object[] args) throws Exception {         if (StrUtil.isBlank(primaryKey)) {             throw new Exception();         }         Map<String, String> map = new HashMap<>(16);         Class<?> entityClz = getEntityClz(targetCls, defaultServiceClass);         BaseService baseService = getBaseService(targetCls, defaultServiceClass);         for (Object arg : args) {             if (arg.getClass().equals(entityClz)) {                 Field declaredField = entityClz.getDeclaredField(primaryKey);                 declaredField.setAccessible(true);                 Object primaryKeyValue = declaredField.get(arg);                 //query the data before edit                 if (null != primaryKeyValue) {                     //query data by primary key                     Object o = baseService.queryId(primaryKeyValue);                     map.put(ASPECT_LOG_OLD_DATA, JsonUtils.obj2Json(o));                     map.put(ASPECT_LOG_NEW_DATA, JsonUtils.obj2Json(arg));                     return map;                 }             }         }         return null;     }      /**      * return JSON data which add operate      *      * @param targetCls           class      * @param args                parameter      * @param defaultServiceClass default service class      * @return add data which will be added      * @throws Exception      */     private String genAddData(Class<?> targetCls, Class<?> defaultServiceClass, Object[] args) throws Exception {         List<Object> parameter = new ArrayList<>();         for (Object arg : args) {             if (arg instanceof HttpServletRequest) {             } else {                 parameter.add(arg);             }         }         return JsonUtils.obj2Json(parameter);     }      /**      * query delete data before delete operate      *      * @param targetCls           class      * @param primaryKey          primaryKey      * @param defaultServiceClass default service class      * @param ids                 ids      * @return delete data which will be deleted      * @throws Throwable      */     private String autoQueryDeletedData(Class<?> targetCls, String primaryKey, Class<?> defaultServiceClass, Object[] ids) throws Throwable {         if (StrUtil.isBlank(primaryKey)) {             throw new OriginException(TipEnum.LOG_ASPECT_PRIMARY_KEY_NOT_EXIST);         }         //get service         BaseService baseService = getBaseService(targetCls, defaultServiceClass);         //get entity         Class<?> entityClz = getEntityClz(targetCls, defaultServiceClass);         //query deleted data by primary key         Query query = new Query();         WhereOperator whereOperator = new WhereOperator(entityClz);         Set<Object> set = new HashSet<>(Arrays.asList((Object[]) ids[0]));         whereOperator.and(primaryKey).in(set.toArray());         query.addWhereOperator(whereOperator);         List list = baseService.queryList(query);         return JsonUtils.obj2Json(list);     }       /**      * return service by targetCls      *      * @param targetCls           current controller class      * @param defaultServiceClass default service class      * @return service instance      * @throws Exception      */     private BaseService getBaseService(Class<?> targetCls, Class<?> defaultServiceClass) throws Exception {         //根據類名拿到對應的 service 名稱         String serviceName = getServiceName(targetCls, defaultServiceClass);         BaseService baseService;         if (null != defaultServiceClass) {             baseService = (BaseService) ApplicationContextProvider.getBean(serviceName, defaultServiceClass);         } else {             Class<?> type = targetCls.getDeclaredField(serviceName).getType();             baseService = (BaseService) ApplicationContextProvider.getBean(serviceName, type);         }         return baseService;     }      /**      * return service name      *      * @param targetCls           current controller class      * @param defaultServiceClass default service class      * @return service name      */     private String getServiceName(Class<?> targetCls, Class<?> defaultServiceClass) {         if (null != defaultServiceClass && Object.class != defaultServiceClass) {             return StrUtil.left(defaultServiceClass.getSimpleName(), 1).toLowerCase() + defaultServiceClass.getSimpleName().substring(1);         }         return StrUtil.left(targetCls.getSimpleName(), 1).toLowerCase() + targetCls.getSimpleName().substring(1).replace("Controller", "Service");     }       /**      * return entity class      *      * @param targetCls           current controller class      * @param defaultServiceClass default service class      * @return entity class      * @throws Exception      */     private Class<?> getEntityClz(Class<?> targetCls, Class<?> defaultServiceClass) {         try {             Class<?> type;             if (null != defaultServiceClass && Object.class != defaultServiceClass) {                 type = defaultServiceClass;             } else {                 type = targetCls.getDeclaredField(getServiceName(targetCls, null)).getType();             }             String entityName = type.getName().replace("service", "entity").replace("Service", "Entity");             Class<?> entityClz = Class.forName(entityName);             return entityClz;         } catch (Exception e) {             log.error("獲取 class 失敗");         }         return null;     }       /**      * require path      *      * @param targetMethod target method      * @param defaultPath  default require path      * @return require path      */     private String getPath(Method targetMethod, String defaultPath) {         String path = defaultPath;         PostMapping postMapping = targetMethod.getAnnotation(PostMapping.class);         GetMapping getMapping = targetMethod.getAnnotation(GetMapping.class);         RequestMapping requestMapping = targetMethod.getAnnotation(RequestMapping.class);         if (null != postMapping) {             path = postMapping.value()[0];         } else if (null != getMapping) {             path = getMapping.value()[0];         } else if (null != requestMapping) {             path = requestMapping.value()[0];         }         return path;     }  }

上面的代碼中我們定義了一個切面指定需要攔截的包名和注解,因為涉及到很多業務相關的代碼,所以不能完整的提供出來,但是整個思路就是這樣的,在每種操作類型前后將需要記錄的數據查詢出來進行記錄。代碼很長主要是用來獲取相應的參數值的,大家使用的時候可以根據自己的需要進行取舍。比如在新增操作的時候,我們將新增的數據進行記錄下來;編輯的時候將編輯前的數據查詢出來和編輯后的數據一起保存起來,刪除也是一樣的,在刪除前將數據查詢出來保存到日志表中。

同樣導出和下載都會記錄相應信息,整個操作類型的代碼如下:

package com.api.annotation;  /**  * <br>  * <b>Function:</b><br>  * <b>Author:</b>@author 子悠<br>  * <b>Date:</b>2020-11-17 22:11<br>  * <b>Desc:</b>無<br>  */ public interface OperationType {     /**      * 新增      **/     String ADD = "add";     /**      * 刪除      **/     String DELETE = "delete";     /**      * 使用實體參數修改      **/     String EDIT = "edit";     /**      * 查詢      **/     String SELECT = "select";      /**      * 新增和修改的保存方法,使用此類型時必須配置主鍵字段名稱      **/     String SAVE = "save";      /**      * 導出      **/     String EXPORT = "export";      /**      * 下載      **/     String DOWNLOAD = "download";  }

后續在使用的時候只需要在需要的方法上加上注解,填上相應的參數即可@OperationLog(desc = "查詢單條記錄", path =  "/data")

到此,相信大家對“怎么使用的Java 注解”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

万荣县| 泽州县| 秭归县| 丹巴县| 蓝山县| 罗甸县| 贡觉县| 嘉义市| 白玉县| 荥经县| 阿克| 棋牌| 南雄市| 阳新县| 阿坝| 高阳县| 山东省| 九龙城区| 全州县| 昭通市| 长泰县| 宜川县| 淳安县| 应城市| 聂拉木县| 襄汾县| 新绛县| 三台县| 从化市| 阿拉善盟| 云和县| 龙川县| 通榆县| 扶沟县| 兴和县| 长宁县| 利津县| 阿勒泰市| 上高县| 巨鹿县| 蚌埠市|