Java注解-元注解

阿飞 2021年04月17日 325次浏览

元注解

@Retention

public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

此注解表明了注解的生命周期

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

有三种,分别是源代码、字节码、和运行时

@Target

public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

表明该注解可以标注在什么位置

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

@Documented

它的作用是能够将注解中的元素包含到 Javadoc 中去。

@Inherited

@Inherited注解了的注解修饰了一个父类,如果他的子类没有被其他注解修饰,则它的子类也继承了父类的注解。

@Repeatable

这个元注解修饰的注解可以同时作用一个对象多次,但是每次作用注解又可以代表不同的含义。

示例

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogType {
    Log [] value();
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(LogType.class)
public @interface Log {

    String value() default "";

}
@Service
public class UserService {

    @Autowired
    private UserManager userManager;


    @Log(value = "记录空间")
    @Log(value = "记录时间")
    public String getUser() {
        return userManager.getUser();
    }

}
@Around("log()")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
        try {
            logger.info("around通知");
            Log[] logs = getMethod(proceedingJoinPoint).getAnnotationsByType(Log.class);
            Stream.of(logs).forEach(x->{
                logger.info(x.value());
            });
            return proceedingJoinPoint.proceed();
        }catch (Throwable e){
            logger.info("方法运行出现异常,{},{}",e,e.getMessage());
         return null;
        }
    }

    protected Method getMethod(ProceedingJoinPoint pjp) {
        Method method = null;
        try {
            MethodSignature ms = (MethodSignature) pjp.getSignature();
            method = pjp.getTarget()
                    .getClass()
                    .getMethod(ms.getName(), ms.getParameterTypes());
        } catch (NoSuchMethodException e) {
            //ignore
        }
        return method;
    }