美文网首页
(009)java实现自定义注解

(009)java实现自定义注解

作者: Lindm | 来源:发表于2018-10-10 17:41 被阅读0次
一、前言

自定义注解可用于记录系统操作日志、查阅记录等,使编码更加灵活。

二、步骤

(1) pom.xml导包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>2.0.3.RELEASE</version>
</dependency>

(2)新建自定义注解类

package com.business.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 查阅记录注解<br/>
 * 文档id:直接从HttpServletRequest上获取参数“docId”
 * @author lindm
 * @date 2018/10/10
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ReadLog {

    String docId() default "";

    // 模块编码
    String moduleId() default "DISPATCH";
}

(3)新建切面类

package com.business.annotation.impl;

import com.business.annotation.ReadLog;
import com.business.constant.AnnotationConstant;
import com.business.service.DocReadLogMng;
import com.egov.utils.exception.BusinessException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.mp4parser.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * 查阅记录注解切面类
 * 注解无法实现动态传参,可采用其他迂回的方式获取参数
 * @author lindm
 * @date 2018/10/10
 */
@Aspect
@Component
public class ReadLogImpl {
    
    @Resource
    private DocReadLogMng docReadLogMng;

    @Pointcut(value = "@annotation(com.business.annotation.ReadLog)")
    public void insertReadLog(){
    }

    /**
     * 方法执行后
     *
     * @param joinPoint
     * @return
     */
    // TODO 待完善
    @After(value = "@annotation(com.business.annotation.ReadLog)")
    public void after(JoinPoint joinPoint) {
        try {
            // 获取请求参数
           // 对于HttpServletRequest在非控制层的操作,使用RequestContextHolder是线程安全的
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                    .getRequestAttributes()).getRequest();
            String docId = request.getParameter(AnnotationConstant.PARAM_ID);

            // 获取方法签名
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            //java reflect相关类,通过反射得到注解
            Method method = signature.getMethod();
            //获取方法注解Log
            ReadLog methodAnnotation = method.getAnnotation(ReadLog.class);
            String moduleId = AnnotationConstant.MODULE_ID;
            if (methodAnnotation != null) {
             // 获取注解静态变量值
                moduleId = methodAnnotation.moduleId();
            }

            // 新增记录
            docReadLogMng.insertReadLog(docId, moduleId);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            throw new BusinessException("新增查阅记录出现异常");
        }
    }
}

(4)新建注解常量类

package com.business.constant;

/**
 *  注解使用的常量
 *  @author lindm
 *  @date 2018/10/10
 */
public class AnnotationConstant {

    public static final String MODULE_ID = "EMAIL";

    public static final String PARAM_ID = "docId";
}

(5)使用@ReadLog注解

/**
     * 根据ID得到详细信息
     *
     * @return
     */
    @GetMapping("/getDetailById")
    @ReadLog(moduleId = "EMAIL")
    public JSONObject getDetailById(@RequestParam("docId") String docId) {
        return this.mng.getDetailById(docId, aid);
    }

(6)新建Mock测试类

package com.web;

import com.business.CommonBusinessConfiguration;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {CommonWebConfiguration.class, CommonBusinessConfiguration.class})
public class DocReadLogTest {

    private MockMvc mvc;

    /**
     * web项目上下文
     */
    @Autowired
    private WebApplicationContext webApplicationContext;


    /**
     * 所有测试方法执行之前执行该方法
     */
    @Before
    public void before() {
        //获取mockmvc对象实例
        mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    /**
     * 查询
     * @throws Exception
     */
    @Test
    @WithUserDetails("test")
    public void getDetailById() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("getDetailById?docId=123"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());
    }

}
三、参考链接

(1)自定义注解实现方法入参与出参的日志打印:
https://my.oschina.net/xiaomingnevermind/blog/1619274
(2)java自定义注解:
https://www.jianshu.com/p/7dcd59bdbb0a
(3)由HttpServletRequest的传值引发的线程安全性问题:
https://www.jianshu.com/p/c7f49658ad04

相关文章

  • (009)java实现自定义注解

    一、前言 自定义注解可用于记录系统操作日志、查阅记录等,使编码更加灵活。 二、步骤 (1) pom.xml导包 (...

  • 注解学习笔记

    什么是注解注解分类注解作用分类 元注解 Java内置注解 自定义注解自定义注解实现及使用编译时注解注解处理器注解处...

  • JAVA之自定义注解

    java的基本注解和元注解,不满足条件时可以自定义注解。声明自定义注解使用@interface关键字实现。 根据注...

  • 一个简单的自定义注解

    1、定义一个自定义注解 2、使用注解 3、利用反射获取注解的值 java注解是怎么实现的?

  • Java自定义注解实现Redis自动缓存

    自定义注解+AOP+范型方法实现Redis自动缓存 相关文章:Java自定义注解动态代理与AOPJava范型 在实...

  • Java中注解学习系列教程-4 使用自定义注解实现excel导出

    本文是《Java中注解学习系列教程》第四篇文章也是小案例文章。 自定义注解小案例是:使用自定义注解实现excel导...

  • 注解原理

    Java内置的注解以及自定义一个注解大家都比较熟悉的了,现在来看看注解实现的原理,看看Java的体系下面是如何对注...

  • 注解原理

    Java内置的注解以及自定义一个注解大家都比较熟悉的了,现在来看看注解实现的原理,看看Java的体系下面是如何对注...

  • 注解原理

    Java内置的注解以及自定义一个注解大家都比较熟悉的了,现在来看看注解实现的原理,看看Java的体系下面是如何对注...

  • 使用Spring Boot的AOP处理自定义注解

    前言 上一篇文章Java 注解介绍讲解了下Java注解的基本使用方式,并且通过自定义注解实现了一个简单的测试工具;...

网友评论

      本文标题:(009)java实现自定义注解

      本文链接:https://www.haomeiwen.com/subject/qhhmaftx.html