springboot自定义注解,怎么搞?
点击上方蓝色字体,选择“标星公众号”
优质文章,第一时间送达
Java枚举
通常springboot的应用场景为:
日志记录: 记录请求信息的日志, 以便进行信息监控, 信息统计, 计算PV(page View)等
性能监控;
权限检查;
通用行为
0. pom引入依赖
org.springframework.boot
spring-boot-starter-aop
1. 自定义注解的范式
@Target 注解
主要说明注解的使用范围,主要包括以下几种类型:
TYPE:类,接口或者枚举
FIELD:域,包含枚举常量
METHOD:方法
PARAMETER:参数
CONSTRUCTOR:构造方法
LOCAL_VARIABLE:局部变量
ANNOTATION_TYPE:注解类型
PACKAGE:包
@Retention 注解
主要说明注解的生命周期,主要包含以下几种类型:
SOURCE:源码级别保留,编译后即丢弃
CLASS:编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值。
RUNTIME: 运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用。
@Documented 注解
主要指明修饰的注解,可以被例如javadoc此类的工具文档化,只负责标记,没有成员取值
2. 具体实现
现在我们自定义一个注解,实现的功能是当系统执行某个函数时,我们打印请求头和登录人的相关信息。
2.1 定义接口
@Target(ElementType.METHOD) //在方法上使用
@Retention(RetentionPolicy.RUNTIME) //运行级别保留
public @interface DetailRequest {
String value() default ""; //使用注解的时候传递,默认为""
}
2.2 切面编程
@Component
@Aspect
@Slf4j
public class MyAspect {
ThreadLocal currentTime = new ThreadLocal<>();
public MyAspect() { //验证是否启动时加载
System.out.println("==========MyAspect start=======================");
}
/**
* 配置切入点
*/
@Pointcut("@annotation(me.zhengjie.annotation.DetailRequest)") //此处对应之前我们定义的接口
public void detailPointcut() {
// 该方法无方法体,主要为了让同类中其他方法使用此切入点
}
/**
* 配置环绕通知,使用在方法logPointcut()上注册的切入点
*
* @param joinPoint join point for advice
*/
@Around("detailPointcut()")
public Object detailAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object result;
currentTime.set(System.currentTimeMillis()); //保存当前时间
result = joinPoint.proceed(); //获得函数运行结果
//操作时长
Long time=System.currentTimeMillis() - currentTime.get();
System.out.println("操作时长:"+time +" 毫秒" );
HttpServletRequest request = RequestHolder.getHttpServletRequest();
//获取ip值
String ip=request.getRemoteAddr();
System.out.println("ip:"+ ip );
//获得浏览器类型
String browser= StringUtils.getBrowser(request); //getBrowser()方法见下面
System.out.println("浏览器类型:"+ browser );
//获取操作时间
Time t =new Time(System.currentTimeMillis());
LocalTime localTime = t.toLocalTime();
String st = localTime.toString(); //获取当前时间(毫秒)转化为标准时间显示
System.out.println("当前操作时间:"+ st );
//获取操作人
String currentUsername = SecurityUtils.getCurrentUsername(); //获取系统登录用户,从cookie或reids中取
System.out.println("当前操作人:"+ currentUsername );
//获取方法名
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
System.out.println("当前具体操作方法:"+ methodName );
//获取描述
Method method = signature.getMethod();
DetailRequest annotation = method.getAnnotation(DetailRequest.class);
String value = annotation.value();
System.out.println("当前具体操作注解名:"+ value ); //获取注解中传递的参数
return result;
}
}
其中所用到的工具类RequestHolder,其定义为
public class RequestHolder {
public static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes)Objects.
requireNonNull(RequestContextHolder.
getRequestAttributes())).getRequest();
}
}
StringUtils.getBrowser()方法定义如下:
public static String getBrowser(HttpServletRequest request) {
UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
Browser browser = userAgent.getBrowser();
return browser.getName();
}
2.3 自定义注解的使用
该函数功能为查询指定表格的所有数据
@GetMapping
@DetailRequest("自定义测试") //传递"自定义测试"字符串
public ResponseEntity
2.4 启动类上添加注解
@EnableAspectJAutoProxy
2.5 观察结果
系统启动时(使用的是eladmin开源框架,具体使用见我的博客):
可以看到已经成功加载自定义注解
接下来,进入指定页面,加载public ResponseEntity query(MyJobQueryCriteria criteria,Pageable pageable),可以看到输出结果:
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:
http://blog.csdn.net/ws6afa88/article/details/108590248
粉丝福利:108本java从入门到大神精选电子书领取
???
?长按上方锋哥微信二维码 2 秒 备注「1234」即可获取资料以及 可以进入java1234官方微信群
感谢点赞支持下哈
评论