自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

天天都在使用的 Java 注解,你真的了解它嗎?

開(kāi)發(fā) 后端
注解(Annotation)是一種可以放在 Java 類(lèi)上,方法上,屬性上,參數(shù)前面的一種特殊的注釋?zhuān)脕?lái)注釋注解的注解叫做元注解。元注解我們平常不會(huì)編寫(xiě),只需要添加到我們自己編寫(xiě)的注解上即可,。

[[353180]]

本文轉(zhuǎn)載自微信公眾號(hào)「Java極客技術(shù)」,作者鴨血粉絲 。轉(zhuǎn)載本文請(qǐng)聯(lián)系Java極客技術(shù)公眾號(hào)。 

Hello,大家好,我是阿粉,Java 的注解相信大家天天都在用,但是關(guān)于注解的原理,大家都了解嗎?這篇文章通過(guò)意見(jiàn)簡(jiǎn)單的示例給大家演示一下注解的使用和原理。

Java 元注解

注解(Annotation)是一種可以放在 Java 類(lèi)上,方法上,屬性上,參數(shù)前面的一種特殊的注釋?zhuān)脕?lái)注釋注解的注解叫做元注解。元注解我們平常不會(huì)編寫(xiě),只需要添加到我們自己編寫(xiě)的注解上即可,。

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

  1. @Target:標(biāo)記這個(gè)注解使用的地方,取值范圍在枚舉 java.lang.annotation.ElementType:TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE,TYPE_PARAMETER,TYPE_USE。
  2. @Retention :標(biāo)識(shí)這個(gè)注解的生命周期,取值范圍在枚舉 java.lang.annotation.RetentionPolicy,SOURCE,CLASS,RUNTIME,一般定義的注解都是在運(yùn)行時(shí)使用,所有要用 @Retention(RetentionPolicy.RUNTIME);
  3. @Documented:表示注解是否包含到文檔中。
  4. @Inherited :使用@Inherited定義子類(lèi)是否可繼承父類(lèi)定義的Annotation。@Inherited僅針對(duì)@Target(ElementType.TYPE)類(lèi)型的annotation有效,并且僅針對(duì)class的繼承,對(duì)interface的繼承無(wú)效。

定義注解

上面介紹了幾個(gè)元注解,下面我們定義一個(gè)日志注解來(lái)演示一下,我們通過(guò)定義一個(gè)名為OperationLog 的注解來(lái)記錄一些通用的操作日志,比如記錄什么時(shí)候什么人查詢(xún)的哪個(gè)表的數(shù)據(jù)或者新增了什么數(shù)據(jù)。編寫(xiě)注解我們用的是 @interface 關(guān)鍵字,相關(guān)代碼如下:

  1. package com.api.annotation; 
  2.  
  3. import java.lang.annotation.*; 
  4.  
  5. /** 
  6.  * <br> 
  7.  * <b>Function:</b><br> 
  8.  * <b>Author:</b>@author 子悠<br> 
  9.  * <b>Date:</b>2020-11-17 22:10<br> 
  10.  * <b>Desc:</b>用于記錄操作日志<br> 
  11.  */ 
  12. @Target({ElementType.METHOD}) 
  13. @Retention(RetentionPolicy.RUNTIME) 
  14. @Documented 
  15. public @interface OperationLog { 
  16.  
  17.     /** 
  18.      * 操作類(lèi)型 
  19.      * 
  20.      * @return 
  21.      */ 
  22.     String type() default OperationType.SELECT
  23.  
  24.     /** 
  25.      * 操作說(shuō)明 
  26.      * 
  27.      * @return 
  28.      */ 
  29.     String desc() default ""
  30.  
  31.     /** 
  32.      * 請(qǐng)求路徑 
  33.      * 
  34.      * @return 
  35.      */ 
  36.     String path() default ""
  37.  
  38.     /** 
  39.      * 是否記錄日志,默認(rèn)是 
  40.      * 
  41.      * @return 
  42.      */ 
  43.     boolean write() default true
  44.  
  45.     /** 
  46.      * 是否需要登錄信息 
  47.      * 
  48.      * @return 
  49.      */ 
  50.     boolean auth() default true
  51.    /** 
  52.      * 當(dāng) type 為 save 時(shí)必須 
  53.      * 
  54.      * @return 
  55.      */ 
  56.     String primaryKey() default ""
  57.  
  58.     /** 
  59.      * 對(duì)應(yīng) service 的 Class 
  60.      * 
  61.      * @return 
  62.      */ 
  63.     Class<?> defaultServiceClass() default Object.class; 

說(shuō)明

上面的注解,我們?cè)黾恿薂Target({ElementType.METHOD}) , @Retention(RetentionPolicy.RUNTIME), @Documented 三個(gè)元注解,表示我們這個(gè)注解是使用在方法上的,并且生命周期是運(yùn)行時(shí),而且可以記錄到文檔中。然后我們可以看到定義注解采用的u是@interface 關(guān)鍵字,并且我們給這個(gè)注解定義了幾個(gè)屬性,同時(shí)設(shè)置了默認(rèn)值。主要注意的是平時(shí)我們編寫(xiě)的注解一般必須設(shè)置@Target和@Retention,而且 @Retention一般設(shè)置為RUNTIME,這是因?yàn)槲覀冏远x的注解通常要求在運(yùn)行期讀取,另外一般情況下,不必寫(xiě)@Inherited。

使用

上面的動(dòng)作只是把注解定義出來(lái)了,但是光光定義出來(lái)是沒(méi)有用的,必須有一個(gè)地方讀取解析,才能提現(xiàn)出注解的價(jià)值,我們就采用 Spring 的 AOP 攔截這個(gè)注解,將所有攜帶這個(gè)注解的方法所進(jìn)行的操作都記錄下來(lái)。

  1. package com.api.config; 
  2.  
  3. import lombok.extern.slf4j.Slf4j; 
  4. import org.aspectj.lang.ProceedingJoinPoint; 
  5. import org.aspectj.lang.annotation.Around; 
  6. import org.aspectj.lang.annotation.Aspect; 
  7. import org.aspectj.lang.annotation.Pointcut; 
  8. import org.aspectj.lang.reflect.MethodSignature; 
  9. import org.springframework.beans.factory.annotation.Autowired; 
  10. import org.springframework.core.annotation.Order
  11. import org.springframework.stereotype.Component; 
  12. import org.springframework.web.bind.annotation.GetMapping; 
  13. import org.springframework.web.bind.annotation.PostMapping; 
  14. import org.springframework.web.bind.annotation.RequestMapping; 
  15.  
  16. import javax.servlet.http.HttpServletRequest; 
  17. import java.lang.reflect.Field; 
  18. import java.lang.reflect.Method; 
  19. import java.util.*; 
  20.  
  21. /** 
  22.  * <br> 
  23.  * <b>Function:</b><br> 
  24.  * <b>Author:</b>@author 子悠<br> 
  25.  * <b>Date:</b>2020-11-17 14:40<br> 
  26.  * <b>Desc:</b>aspect for operation log<br> 
  27.  */ 
  28. @Aspect 
  29. @Component 
  30. @Order(-5) 
  31. @Slf4j 
  32. public class LogAspect { 
  33.     /** 
  34.      * Pointcut for methods which need to record operate log 
  35.      */ 
  36.     @Pointcut("within(com.xx.yy.controller..*) && @annotation(com.api.annotation.OperationLog)"
  37.     public void logAspect() { 
  38.     } 
  39.  
  40.     /** 
  41.      * record log for Admin and DSP 
  42.      * 
  43.      * @param joinPoint parameter 
  44.      * @return result 
  45.      * @throws Throwable 
  46.      */ 
  47.     @Around("logAspect()"
  48.     public Object around(ProceedingJoinPoint joinPoint) throws Throwable { 
  49.         Object proceed = null
  50.         String classType = joinPoint.getTarget().getClass().getName(); 
  51.         Class<?> targetCls = Class.forName(classType); 
  52.         MethodSignature ms = (MethodSignature) joinPoint.getSignature(); 
  53.         Method targetMethod = targetCls.getDeclaredMethod(ms.getName(), ms.getParameterTypes()); 
  54.         OperationLog operation = targetMethod.getAnnotation(OperationLog.class); 
  55.         if (null != operation && operation.write()) { 
  56.             SysMenuOpLogEntity opLogEntity = new SysMenuOpLogEntity(); 
  57.             StringBuilder change = new StringBuilder(); 
  58.             if (StrUtil.isNotBlank(operation.type())) { 
  59.                 switch (operation.type()) { 
  60.                     case OperationType.ADD
  61.                         proceed = joinPoint.proceed(); 
  62.                         String addString = genAddData(targetCls, operation.defaultServiceClass(), joinPoint.getArgs()); 
  63.                         opLogEntity.setAfterJson(addString); 
  64.                         change.append(OperationType.ADD); 
  65.                         break; 
  66.                     case OperationType.DELETE
  67.                         String deleteString = autoQueryDeletedData(targetCls, operation.primaryKey(), operation.defaultServiceClass(), joinPoint.getArgs()); 
  68.                         opLogEntity.setBeforeJson(deleteString); 
  69.                         change.append(OperationType.DELETE); 
  70.                         proceed = joinPoint.proceed(); 
  71.                         break; 
  72.                     case OperationType.EDIT: 
  73.                         change.append(OperationType.EDIT); 
  74.                         setOpLogEntity(opLogEntity, targetCls, operation.primaryKey(), operation.defaultServiceClass(), joinPoint.getArgs()); 
  75.                         proceed = joinPoint.proceed(); 
  76.                         break; 
  77.                     case OperationType.SELECT
  78.                         opLogEntity.setBeforeJson(getQueryString(targetCls, operation.defaultServiceClass(), joinPoint.getArgs())); 
  79.                         change.append(operation.type()); 
  80.                         proceed = joinPoint.proceed(); 
  81.                         break; 
  82.                     case OperationType.SAVE: 
  83.                         savedDataOpLog(opLogEntity, targetCls, operation.primaryKey(), operation.defaultServiceClass(), joinPoint.getArgs()); 
  84.                         change.append(operation.type()); 
  85.                         proceed = joinPoint.proceed(); 
  86.                         break; 
  87.                     case OperationType.EXPORT: 
  88.                     case OperationType.DOWNLOAD: 
  89.                         change.append(operation.type()); 
  90.                         proceed = joinPoint.proceed(); 
  91.                         break; 
  92.                     default
  93.                 } 
  94.                 opLogEntity.setExecType(operation.type()); 
  95.             } 
  96.             StringBuilder changing = new StringBuilder(); 
  97.             if (StrUtil.isNotBlank(opLogEntity.getExecType())) { 
  98.                 if (operation.auth()) { 
  99.                     LoginUserVO loginUser = getLoginUser(); 
  100.                     if (null != loginUser) { 
  101.                         opLogEntity.setUserId(loginUser.getUserId()); 
  102.                         opLogEntity.setUserName(loginUser.getUserName()); 
  103.                         changing.append(loginUser.getUserName()).append("-"); 
  104.                     } else { 
  105.                         log.error("用戶未登錄"); 
  106.                     } 
  107.                 } 
  108.                 opLogEntity.setCreateTime(DateUtils.getCurDate()); 
  109.                 opLogEntity.setRemark(getOperateMenuName(targetMethod, operation.desc())); 
  110.                 opLogEntity.setPath(getPath(targetMethod, targetMethod.getName())); 
  111.                 opLogEntity.setChanging(changing.append(change).toString()); 
  112.                 menuOpLogService.save(opLogEntity); 
  113.             } 
  114.         } 
  115.         return proceed; 
  116.     } 
  117.  
  118.     /** 
  119.      * query data by userId 
  120.      * 
  121.      * @param targetCls           class 
  122.      * @param defaultServiceClass default service class 
  123.      * @return 
  124.      * @throws Exception 
  125.      */ 
  126.     private String queryByCurrentUserId(Class<?> targetCls, Class<?> defaultServiceClass) throws Exception { 
  127.         BaseService baseService = getBaseService(targetCls, defaultServiceClass); 
  128.         LoginUserVO loginUser = dspBaseService.getLoginUser(); 
  129.         if (null != loginUser) { 
  130.             Object o = baseService.queryId(loginUser.getUserId()); 
  131.             return JsonUtils.obj2Json(o); 
  132.         } 
  133.         return null
  134.     } 
  135.  
  136.     /** 
  137.      * return query parameter 
  138.      * 
  139.      * @param targetCls           class 
  140.      * @param args                parameter 
  141.      * @param defaultServiceClass default service class 
  142.      * @return 
  143.      * @throws Exception 
  144.      */ 
  145.     private String getQueryString(Class<?> targetCls, Class<?> defaultServiceClass, Object[] args) { 
  146.         if (args.length > 0) { 
  147.             Class<?> entityClz = getEntityClz(targetCls, defaultServiceClass); 
  148.             for (Object arg : args) { 
  149.                 if (arg.getClass().equals(entityClz) || arg instanceof BaseModel) { 
  150.                     return JsonUtils.obj2Json(arg); 
  151.                 } 
  152.             } 
  153.         } 
  154.         return null
  155.     } 
  156.  
  157.     /** 
  158.      * save record log while OperatorType is SAVE 
  159.      * 
  160.      * @param opLogEntity         entity 
  161.      * @param targetCls           class 
  162.      * @param primaryKey          primaryKey 
  163.      * @param defaultServiceClass default service class 
  164.      * @param args                parameter 
  165.      * @throws Exception 
  166.      */ 
  167.     private void savedDataOpLog(SysMenuOpLogEntity opLogEntity, Class<?> targetCls, String primaryKey, Class<?> defaultServiceClass, Object[] args) throws Exception { 
  168.         Class<?> entityClz = getEntityClz(targetCls, defaultServiceClass); 
  169.         BaseService baseService = getBaseService(targetCls, defaultServiceClass); 
  170.         for (Object arg : args) { 
  171.             if (arg.getClass().equals(entityClz)) { 
  172.                 if (StrUtil.isNotBlank(primaryKey)) { 
  173.                     Field declaredField = entityClz.getDeclaredField(primaryKey); 
  174.                     declaredField.setAccessible(true); 
  175.                     Object primaryKeyValue = declaredField.get(arg); 
  176.                     //if primary key is not null that means edit, otherwise is add 
  177.                     if (null != primaryKeyValue) { 
  178.                         //query data by primary key 
  179.                         Object o = baseService.queryId(primaryKeyValue); 
  180.                         opLogEntity.setBeforeJson(JsonUtils.obj2Json(o)); 
  181.                     } 
  182.                 } 
  183.                 opLogEntity.setAfterJson(JsonUtils.obj2Json(arg)); 
  184.             } 
  185.         } 
  186.     } 
  187.  
  188.     /** 
  189.      * set parameter which edit data 
  190.      * 
  191.      * @param opLogEntity         entity 
  192.      * @param targetCls           class 
  193.      * @param primaryKey          primaryKey 
  194.      * @param defaultServiceClass default service class 
  195.      * @param args                parameter 
  196.      * @throws Exception 
  197.      */ 
  198.     private void setOpLogEntity(SysMenuOpLogEntity opLogEntity, Class<?> targetCls, String primaryKey, Class<?> defaultServiceClass, Object[] args) throws Exception { 
  199.         Map<String, String> saveMap = autoQueryEditedData(targetCls, primaryKey, defaultServiceClass, args); 
  200.         if (null != saveMap) { 
  201.             if (saveMap.containsKey(ASPECT_LOG_OLD_DATA)) { 
  202.                 opLogEntity.setBeforeJson(saveMap.get(ASPECT_LOG_OLD_DATA)); 
  203.             } 
  204.             if (saveMap.containsKey(ASPECT_LOG_NEW_DATA)) { 
  205.                 opLogEntity.setBeforeJson(saveMap.get(ASPECT_LOG_NEW_DATA)); 
  206.             } 
  207.         } 
  208.     } 
  209.  
  210.     /** 
  211.      * query data for edit and after edit operate 
  212.      * 
  213.      * @param targetCls           class 
  214.      * @param primaryKey          primaryKey 
  215.      * @param defaultServiceClass default service class 
  216.      * @param args                parameter 
  217.      * @return map which data 
  218.      * @throws Exception 
  219.      */ 
  220.     private Map<String, String> autoQueryEditedData(Class<?> targetCls, String primaryKey, Class<?> defaultServiceClass, Object[] args) throws Exception { 
  221.         if (StrUtil.isBlank(primaryKey)) { 
  222.             throw new Exception(); 
  223.         } 
  224.         Map<String, String> map = new HashMap<>(16); 
  225.         Class<?> entityClz = getEntityClz(targetCls, defaultServiceClass); 
  226.         BaseService baseService = getBaseService(targetCls, defaultServiceClass); 
  227.         for (Object arg : args) { 
  228.             if (arg.getClass().equals(entityClz)) { 
  229.                 Field declaredField = entityClz.getDeclaredField(primaryKey); 
  230.                 declaredField.setAccessible(true); 
  231.                 Object primaryKeyValue = declaredField.get(arg); 
  232.                 //query the data before edit 
  233.                 if (null != primaryKeyValue) { 
  234.                     //query data by primary key 
  235.                     Object o = baseService.queryId(primaryKeyValue); 
  236.                     map.put(ASPECT_LOG_OLD_DATA, JsonUtils.obj2Json(o)); 
  237.                     map.put(ASPECT_LOG_NEW_DATA, JsonUtils.obj2Json(arg)); 
  238.                     return map; 
  239.                 } 
  240.             } 
  241.         } 
  242.         return null
  243.     } 
  244.  
  245.     /** 
  246.      * return JSON data which add operate 
  247.      * 
  248.      * @param targetCls           class 
  249.      * @param args                parameter 
  250.      * @param defaultServiceClass default service class 
  251.      * @return add data which will be added 
  252.      * @throws Exception 
  253.      */ 
  254.     private String genAddData(Class<?> targetCls, Class<?> defaultServiceClass, Object[] args) throws Exception { 
  255.         List<Object> parameter = new ArrayList<>(); 
  256.         for (Object arg : args) { 
  257.             if (arg instanceof HttpServletRequest) { 
  258.             } else { 
  259.                 parameter.add(arg); 
  260.             } 
  261.         } 
  262.         return JsonUtils.obj2Json(parameter); 
  263.     } 
  264.  
  265.     /** 
  266.      * query delete data before delete operate 
  267.      * 
  268.      * @param targetCls           class 
  269.      * @param primaryKey          primaryKey 
  270.      * @param defaultServiceClass default service class 
  271.      * @param ids                 ids 
  272.      * @return delete data which will be deleted 
  273.      * @throws Throwable 
  274.      */ 
  275.     private String autoQueryDeletedData(Class<?> targetCls, String primaryKey, Class<?> defaultServiceClass, Object[] ids) throws Throwable { 
  276.         if (StrUtil.isBlank(primaryKey)) { 
  277.             throw new OriginException(TipEnum.LOG_ASPECT_PRIMARY_KEY_NOT_EXIST); 
  278.         } 
  279.         //get service 
  280.         BaseService baseService = getBaseService(targetCls, defaultServiceClass); 
  281.         //get entity 
  282.         Class<?> entityClz = getEntityClz(targetCls, defaultServiceClass); 
  283.         //query deleted data by primary key 
  284.         Query query = new Query(); 
  285.         WhereOperator whereOperator = new WhereOperator(entityClz); 
  286.         Set<Object> set = new HashSet<>(Arrays.asList((Object[]) ids[0])); 
  287.         whereOperator.and(primaryKey).in(set.toArray()); 
  288.         query.addWhereOperator(whereOperator); 
  289.         List list = baseService.queryList(query); 
  290.         return JsonUtils.obj2Json(list); 
  291.     } 
  292.  
  293.  
  294.     /** 
  295.      * return service by targetCls 
  296.      * 
  297.      * @param targetCls           current controller class 
  298.      * @param defaultServiceClass default service class 
  299.      * @return service instance 
  300.      * @throws Exception 
  301.      */ 
  302.     private BaseService getBaseService(Class<?> targetCls, Class<?> defaultServiceClass) throws Exception { 
  303.         //根據(jù)類(lèi)名拿到對(duì)應(yīng)的 service 名稱(chēng) 
  304.         String serviceName = getServiceName(targetCls, defaultServiceClass); 
  305.         BaseService baseService; 
  306.         if (null != defaultServiceClass) { 
  307.             baseService = (BaseService) ApplicationContextProvider.getBean(serviceName, defaultServiceClass); 
  308.         } else { 
  309.             Class<?> type = targetCls.getDeclaredField(serviceName).getType(); 
  310.             baseService = (BaseService) ApplicationContextProvider.getBean(serviceName, type); 
  311.         } 
  312.         return baseService; 
  313.     } 
  314.  
  315.     /** 
  316.      * return service name 
  317.      * 
  318.      * @param targetCls           current controller class 
  319.      * @param defaultServiceClass default service class 
  320.      * @return service name 
  321.      */ 
  322.     private String getServiceName(Class<?> targetCls, Class<?> defaultServiceClass) { 
  323.         if (null != defaultServiceClass && Object.class != defaultServiceClass) { 
  324.             return StrUtil.left(defaultServiceClass.getSimpleName(), 1).toLowerCase() + defaultServiceClass.getSimpleName().substring(1); 
  325.         } 
  326.         return StrUtil.left(targetCls.getSimpleName(), 1).toLowerCase() + targetCls.getSimpleName().substring(1).replace("Controller""Service"); 
  327.     } 
  328.  
  329.  
  330.     /** 
  331.      * return entity class 
  332.      * 
  333.      * @param targetCls           current controller class 
  334.      * @param defaultServiceClass default service class 
  335.      * @return entity class 
  336.      * @throws Exception 
  337.      */ 
  338.     private Class<?> getEntityClz(Class<?> targetCls, Class<?> defaultServiceClass) { 
  339.         try { 
  340.             Class<?> type; 
  341.             if (null != defaultServiceClass && Object.class != defaultServiceClass) { 
  342.                 type = defaultServiceClass; 
  343.             } else { 
  344.                 type = targetCls.getDeclaredField(getServiceName(targetCls, null)).getType(); 
  345.             } 
  346.             String entityName = type.getName().replace("service""entity").replace("Service""Entity"); 
  347.             Class<?> entityClz = Class.forName(entityName); 
  348.             return entityClz; 
  349.         } catch (Exception e) { 
  350.             log.error("獲取 class 失敗"); 
  351.         } 
  352.         return null
  353.     } 
  354.  
  355.  
  356.     /** 
  357.      * require path 
  358.      * 
  359.      * @param targetMethod target method 
  360.      * @param defaultPath  default require path 
  361.      * @return require path 
  362.      */ 
  363.     private String getPath(Method targetMethod, String defaultPath) { 
  364.         String path = defaultPath; 
  365.         PostMapping postMapping = targetMethod.getAnnotation(PostMapping.class); 
  366.         GetMapping getMapping = targetMethod.getAnnotation(GetMapping.class); 
  367.         RequestMapping requestMapping = targetMethod.getAnnotation(RequestMapping.class); 
  368.         if (null != postMapping) { 
  369.             path = postMapping.value()[0]; 
  370.         } else if (null != getMapping) { 
  371.             path = getMapping.value()[0]; 
  372.         } else if (null != requestMapping) { 
  373.             path = requestMapping.value()[0]; 
  374.         } 
  375.         return path; 
  376.     } 
  377.  

上面的代碼中我們定義了一個(gè)切面指定需要攔截的包名和注解,因?yàn)樯婕暗胶芏鄻I(yè)務(wù)相關(guān)的代碼,所以不能完整的提供出來(lái),但是整個(gè)思路就是這樣的,在每種操作類(lèi)型前后將需要記錄的數(shù)據(jù)查詢(xún)出來(lái)進(jìn)行記錄。代碼很長(zhǎng)主要是用來(lái)獲取相應(yīng)的參數(shù)值的,大家使用的時(shí)候可以根據(jù)自己的需要進(jìn)行取舍。比如在新增操作的時(shí)候,我們將新增的數(shù)據(jù)進(jìn)行記錄下來(lái);編輯的時(shí)候?qū)⒕庉嬊暗臄?shù)據(jù)查詢(xún)出來(lái)和編輯后的數(shù)據(jù)一起保存起來(lái),刪除也是一樣的,在刪除前將數(shù)據(jù)查詢(xún)出來(lái)保存到日志表中。

同樣導(dǎo)出和下載都會(huì)記錄相應(yīng)信息,整個(gè)操作類(lèi)型的代碼如下:

  1. package com.api.annotation; 
  2.  
  3. /** 
  4.  * <br> 
  5.  * <b>Function:</b><br> 
  6.  * <b>Author:</b>@author 子悠<br> 
  7.  * <b>Date:</b>2020-11-17 22:11<br> 
  8.  * <b>Desc:</b>無(wú)<br> 
  9.  */ 
  10. public interface OperationType { 
  11.     /** 
  12.      * 新增 
  13.      **/ 
  14.     String ADD = "add"
  15.     /** 
  16.      * 刪除 
  17.      **/ 
  18.     String DELETE = "delete"
  19.     /** 
  20.      * 使用實(shí)體參數(shù)修改 
  21.      **/ 
  22.     String EDIT = "edit"
  23.     /** 
  24.      * 查詢(xún) 
  25.      **/ 
  26.     String SELECT = "select"
  27.  
  28.     /** 
  29.      * 新增和修改的保存方法,使用此類(lèi)型時(shí)必須配置主鍵字段名稱(chēng) 
  30.      **/ 
  31.     String SAVE = "save"
  32.  
  33.     /** 
  34.      * 導(dǎo)出 
  35.      **/ 
  36.     String EXPORT = "export"
  37.  
  38.     /** 
  39.      * 下載 
  40.      **/ 
  41.     String DOWNLOAD = "download"
  42.  

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

總結(jié)

注解一個(gè)我們天天再用的東西,雖然不難,但是我們卻很少自己去寫(xiě)注解的代碼,通過(guò)這篇文章能給大家展示一下注解的使用邏輯,希望對(duì)大家有幫助。Spring 中的各種注解本質(zhì)上也是這種邏輯都需要定義使用和解析。很多時(shí)候我們可以通過(guò)自定義注解去解決很多場(chǎng)景,比如日志,緩存等。

 

責(zé)任編輯:武曉燕 來(lái)源: Java極客技術(shù)
相關(guān)推薦

2024-01-08 08:27:11

注解Bean代理

2023-06-08 11:57:15

Matter協(xié)議家庭智能

2024-08-22 08:17:55

C#工具循環(huán)

2019-09-02 08:39:02

路由器RAM內(nèi)存

2017-12-07 15:00:00

筆記本OLED屏幕

2023-05-29 08:11:42

@Value注解Bean

2023-11-01 13:48:00

反射java

2022-07-26 00:00:22

HTAP系統(tǒng)數(shù)據(jù)庫(kù)

2014-04-17 16:42:03

DevOps

2025-01-03 08:09:15

2022-01-17 07:32:34

Java參數(shù)方法

2023-05-10 11:07:18

2019-09-16 08:40:42

2014-11-28 10:31:07

Hybrid APP

2020-02-27 10:49:26

HTTPS網(wǎng)絡(luò)協(xié)議TCP

2023-03-16 10:49:55

2021-01-15 07:44:21

SQL注入攻擊黑客

2021-11-09 09:48:13

Logging python模塊

2018-12-21 11:24:55

Java時(shí)間處理編程語(yǔ)言

2021-11-26 08:07:16

MySQL SQL 語(yǔ)句數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)