1. Annotation type
Java annotation is used to provide metadata for Java code. You can obtain the specified annotation object through reflection, and then obtain the metadata information in the annotation.
Java annotations have four standard meta annotations: @ Target, @ Retention, @ Documented, @ Inherited.
1.1 @Target
@Target describes the object range modified by Annotation, which is commonly used as follows:
-
@Target(ElementType.TYPE): function interface, class, enumeration and annotation
-
@Target(ElementType.FIELD): constant used for attribute fields and enumerations
-
@Target(ElementType.METHOD): action method
-
@Target(ElementType.PARAMETER): action method parameter
1.2 @Retention
Retention defines the length of time the Annotation is retained, indicating the level at which Annotation information needs to be saved for tracing
The life cycle of the described annotation (i.e. to what extent the described annotation is valid)
-
@The Retention(RetentionPolicy.SOURCE) annotation only exists in the source code and is not included in the class bytecode file
-
@Retention(RetentionPolicy.CLASS) is the default policy, which exists in the class bytecode file, but cannot be obtained at runtime
-
@Retention(RetentionPolicy.RUNTIME) exists in the class bytecode file and can be obtained through reflection at runtime
In development, the user-defined annotation is used during the program running, so @ Retention(RetentionPolicy.RUNTIME) is used by default
1.3 @Documented
@Documented is used to include elements in annotations into Javadoc.
1.4 @Inherited
@Inherited meta annotation is a tag annotation, @ inherited describes that a marked type is inherited.
If the annotation with @ Inherited meta annotation modifies a class and its subclass is not modified by other annotations, its subclass will inherit the annotation of the parent class.
2. Custom annotation implementation
- Custom annotations can be used with AOP, such as logging.
- User defined annotations can be directly used in a method in conjunction with the reflection mechanism.
- The user-defined annotation can be used with the interceptor. Whether to verify the token.
2.1 creating annotations
Create custom annotation: SysLog
Annotations can have no attribute fields
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SysLog { /** * Module */ String model() default ""; /** * Interface name */ String name() default ""; /** * Function code * * @return */ String[] code() default ""; }
2.2 AOP implementation
Join the AOP class SysLogAspect and use the custom annotation SysLog as the entry point, as follows:
@Aspect @Component public class SysLogAspect { /** * Filter class * Specify custom annotations as pointcuts **/ @Pointcut("@annotation(com.lhz.mail.test.SysLog)") public void logPoint() { } /** * Surround the notification and call the target method */ @Around("logPoint()") public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { Signature signature = proceedingJoinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); if (method != null) { SysLog sysLog = method.getAnnotation(SysLog.class); // Gets the attribute value of the annotation String[] code = sysLog.code(); String name = sysLog.name(); String model = sysLog.model(); System.out.println("code: " + Arrays.toString(code)); System.out.println("name: " + name); System.out.println("model: " + model); } return proceedingJoinPoint.proceed(); } }
2.3 reflection realization
You can directly use the reflection mechanism to judge whether there are annotations for a class, method and field, as follows:
public static void main(String[] args) { // Determine whether @ SysLog exists on the Person class: Class<Person> clazz = Person.class; boolean isAnnotation = clazz.isAnnotationPresent(SysLog.class); if (isAnnotation) { SysLog sysLog = clazz.getAnnotation((SysLog.class)); String model = sysLog.model(); String name = sysLog.name(); } } public static void main2(String[] args) { // Determine whether @ SysLog exists on the method of Person class: Class<Person> clazz = Person.class; // method Method[] methods = clazz.getMethods(); for (Method method : methods) { boolean isAnnotation = method.isAnnotationPresent(SysLog.class); if (isAnnotation) { System.out.println("method:" + method.getName() + "There are custom annotations"); SysLog sysLog = method.getAnnotation((SysLog.class)); String model = sysLog.model(); String name = sysLog.name(); } } } public static void main3(String[] args) { // Judge whether @ SysLog exists in the field of Person class: Class<Person> clazz = Person.class; // method Field[] fields = clazz.getFields(); for (Field field : fields) { boolean isAnnotation = field.isAnnotationPresent(SysLog.class); if (isAnnotation) { System.out.println("Field:" + field.getName() + "Custom annotation exists"); SysLog sysLog = field.getAnnotation((SysLog.class)); String model = sysLog.model(); String name = sysLog.name(); } } }
2.4 interceptor implementation
Cooperate with the interceptor to determine whether a request does not need token verification. The logic is as follows:
1. Create annotation IgnoreToken
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface IgnoreToken { }
2. Controller load annotation:
@IgnoreToken @GetMapping("test") public Object test() { return object; }
3. Interceptor judgment comments:
@Component public class AuthenticationHandlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.debug("Entry interceptor,URL:{}", request.getServletPath()); Method method = ((HandlerMethod) handler).getMethod(); // Judge whether the method requesting the interface has the IgnoreToken annotation if (method.isAnnotationPresent(IgnoreToken.class)) { return true; }else{ // token verification logic ... } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }