aop+自定义注解
自定义注解,并且实现,需要两个文件;
自定义注解类:
package com.clc.server.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(value = {ElementType.TYPE, ElementType.METHOD})//使用位置(类,方法) @Retention(RetentionPolicy.RUNTIME)//加载到jvm里运行 public @interface Clc { String value(); //注解的属性,如果只有一个属性,一般叫value String name() default ""; //属性,默认值"",可以不写 }
定义好注解后,需要解析类来实现,此处使用aop来实现;
package com.clc.server.aop; import com.clc.server.annotation.Clc; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import java.lang.reflect.Method; /** * 解析clc注解使用 */ @Aspect//来定义一个切面 @Component public class ClcAop { //定义切入点 @Pointcut("@annotation(com.clc.server.annotation.Clc)") public void auditAspect() { System.out.println("1221212132"); } //通知 @Before("auditAspect()") public void doBefore(JoinPoint joinPoint) { System.out.println("触发到 @Before(\"auditAspect()\")"); } /** * 后置通知 * * @param joinPoint 切点 */ @AfterReturning("auditAspect()") public void doAfrterReturning(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); System.out.println("触发 @AfterReturning(\"auditAspect()\")"); System.out.println(args.length); getControllerMethodDescription(joinPoint); } /** * 获取注解中对方法的描述信息 * * @param joinPoint 切点 * @return 方法描述 */ public static void getControllerMethodDescription(JoinPoint joinPoint) { String targetName = joinPoint.getTarget().getClass().getName(); //获得执行方法的类名 String methodName = joinPoint.getSignature().getName(); //获得执行方法的方法名 Object[] arguments = joinPoint.getArgs(); //获取切点方法的所有参数类型 try { Class targetClass = Class.forName(targetName); Method[] methods = targetClass.getMethods(); //获取公共方法,不包括类私有的 String value = ""; String name = ""; for (Method method : methods) { if (method.getName().equals(methodName)) { Class[] clazzs = method.getParameterTypes(); //对比方法中参数的个数 if (clazzs.length == arguments.length) { value = method.getAnnotation(Clc.class).value(); name = method.getAnnotation(Clc.class).name(); break; } } } System.out.println("value=" + value); System.out.println("name=" + name); } catch (Exception e) { e.printStackTrace(); } } }
测试注解,使用
/** * 测试自定义注解 */ @Clc(value = "clc", name = "name") @RequestMapping(value = "/add2", method = RequestMethod.GET) public String add2() { //获取本服务的信息 ServiceInstance instance = client.getLocalServiceInstance(); Integer r = 2; String info = "/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + "结果:" + r; logger.info(info); return info; }
触发注解后:
2018-09-13 20:11:07.487 INFO 14012 --- [nio-9003-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet' 2018-09-13 20:11:07.487 INFO 14012 --- [nio-9003-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started 2018-09-13 20:11:07.514 INFO 14012 --- [nio-9003-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 27 ms 触发到 @Before("auditAspect()") 2018-09-13 20:11:07.554 INFO 14012 --- [nio-9003-exec-1] c.c.s.c.ComputeController@7fcff1b9 : /add, host:localhost, service_id:clc-service结果:2 触发 @AfterReturning("auditAspect()") 0 value=clc name=name 2018-09-13 20:15:44.844 INFO 14012 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration
简单的自定义注解,已经实现
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
2017-09-13 识别jar的编译JDK版本