//除了@符号,注解很像是一个接口。 //定义注解的时候需要用到元注解,@Target和@Retention。 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Test { /** 标题 */ //public String title() default ""; //在注解中一般会有一些元素以表示某些值。可以为其制定默认值。没有元素的注解称为标记注解 }
下面看一个定义了元素的注解。
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Test { public int id (); /** 标题元素 */ public String title () default "标题元素"; } //定义了注解,必然要去使用注解。 public class Utils { @Test(id = 1, title = "va测试工具标题") public boolean vaTest (String vaTest) { if ("vaTest".equals(vaTest)) { return true; } return false; } @Test(id = 2) public String enTest (String enTest) { return enTest + "java第一"; } }
使用注解最主要的部分在于对注解的处理,那么就会涉及到注解处理器。
原理上讲,注解处理器就是通过反射机制获取被检查方法上的注解信息,然后根据注解元素的值进行不同处理。
public static void main (String[] args) { trackTest(Utils.class); } public static void trackTest (Class<?> cl) { for (Method m : cl.getDeclaredMethods()) { Test test = m.getAnnotation(Test.class); if (test != null) { System.out.println("结果:" + test.id() + " " + test.title()); } } }
import java.lang.annotation.*; /** * 自定义操作日志记录注解 * * @author n */ @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface TestAnnotation{ /** * id */ public int id() ; /** * 模块标题 */ public String title() default ""; }
@Slf4j @RestController @RequestMapping("/admin") public class AdminController { @PostMapping(value = "/update/{id}") @Log(title = "管理",int = 1) public Object updateAdmin(@PathVariable Long id) { //操作...... return null; } }
/** * 操作日志记录处理 * * @author n */ @Aspect @Component @Order(3) public class TestAspect { private static final Logger logs = LoggerFactory.getLogger(TestAspect .class); // 配置织入点 @Pointcut("@annotation(com.*.log.annotation.TestAnnotation)") public void TestPointCut () { } /** * 处理完请求后执行 * * @param pjp 切点 */ @Around(value = "TestPointCut ()") public Object doAround (ProceedingJoinPoint pjp) throws Throwable { // 获得注解 Signature signature = pjp.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); TestAnnotation test= method.getAnnotation(TestAnnotation.class); if (test!= null) { //模块标题 String title = test.title(); //id int id= test.id(); //其他操作 } Object proceed = null; try { proceed = pjp.proceed(); } catch (Throwable e) { //其他异常操作 throw e; } return proceed; } }