自定义注解
1、声明一个自定义注解
● ElementType.CONSTRUCTOR:用于描述构造器
● ElementType.FIELD:成员变量、对象、属性(包括enum实例)
● ElementType.LOCAL_VARIABLE:用于描述局部变量
● ElementType.METHOD:用于描述方法
● ElementType.PACKAGE:用于描述包
● ElementType.PARAMETER:用于描述参数
● ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明
(2)@Retention:定义该注解的生命周期,共有三种:
● RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
● RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
● RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
(3)@Documented:表示将注解包含在javaDoc中
(4)@Inhertied:表示允许子类继承父类中的注解
2、注解中的元素
注解是用来完成一个切面的需求,有可能需要传入一些参数
(1)注解中的元素支持的类型:
1.基本类型(如:int、boolean等)
2.String
3.Class
4.enum
5.annotation
6.以上类的数组类型
注:数组传值方式:@LimitedAccess(params = {"temp","paomo"})
(2)元素的声明
例如:
1.必须要传值的元素声明方式
String value();
2.非必传的方式(加上默认值即可)
String value() default "poamo";
注解实现(即aop切面的实现)
1、自定义切面类
@Aspect放在类头上,把这个类作为一个切面。
@Pointcut放在方法头上,定义一个可被别的方法引用的切入点表达式。
2、5种通知方式
● @Before,前置通知,放在方法头上。
● @After,后置【finally】通知,放在方法头上。
● @AfterReturning,后置【try】通知,放在方法头上,使用returning来引用方法返回值。
● @AfterThrowing,后置【catch】通知,放在方法头上,使用throwing来引用抛出的异常。
1、声明一个自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LimitedAccess {}
注:(1)@Target:声明的区域● ElementType.CONSTRUCTOR:用于描述构造器
● ElementType.FIELD:成员变量、对象、属性(包括enum实例)
● ElementType.LOCAL_VARIABLE:用于描述局部变量
● ElementType.METHOD:用于描述方法
● ElementType.PACKAGE:用于描述包
● ElementType.PARAMETER:用于描述参数
● ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明
(2)@Retention:定义该注解的生命周期,共有三种:
● RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
● RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
● RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
(3)@Documented:表示将注解包含在javaDoc中
(4)@Inhertied:表示允许子类继承父类中的注解
2、注解中的元素
注解是用来完成一个切面的需求,有可能需要传入一些参数
(1)注解中的元素支持的类型:
1.基本类型(如:int、boolean等)
2.String
3.Class
4.enum
5.annotation
6.以上类的数组类型
注:数组传值方式:@LimitedAccess(params = {"temp","paomo"})
(2)元素的声明
例如:
1.必须要传值的元素声明方式
String value();
2.非必传的方式(加上默认值即可)
String value() default "poamo";
注解实现(即aop切面的实现)
1、自定义切面类
@Aspect放在类头上,把这个类作为一个切面。
@Pointcut放在方法头上,定义一个可被别的方法引用的切入点表达式。
2、5种通知方式
● @Before,前置通知,放在方法头上。
● @After,后置【finally】通知,放在方法头上。
● @AfterReturning,后置【try】通知,放在方法头上,使用returning来引用方法返回值。
● @AfterThrowing,后置【catch】通知,放在方法头上,使用throwing来引用抛出的异常。
● @Around,环绕通知,放在方法头上,这个方法要决定真实的方法是否执行,而且必须有返回值。
@Aspect
@Component
public class LimitedAccessAop {
private final String LimitedAccessPoint = "@annotation(com.future.balanceapi.common.annotation.LimitedAccess)";
@Pointcut(LimitedAccessPoint)
public void annotationPointcut() {};
/**
* @Before、@After、@AfterReturning的形参都是JoinPoint
*/
@AfterReturning(LimitedAccessPoint)
public String after(JoinPoint joinPoint) {
MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
Method method = methodSignature.getMethod();
LimitedAccess annotation = method.getAnnotation(LimitedAccess.class);
}
/**
* @Around的形参是ProceedingJoinPoint
*/
@Around(LimitedAccessPoint)
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//做业务逻辑....
//如果需要继续执行方法
return proceedingJoinPoint.proceed();
//如果不需要继续执行方法,而是拦截返回自定义数据
ResultData resultDataTemp = new ResultData();
resultDataTemp.setData(null);
resultDataTemp.setRtnInfo("访问过于频繁,请稍候再试");
return resultDataTemp;
}
}