定义一个注解
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 MyAnnotation {
String descrption() default ""; // 描述
}
@Target表示注解可以使用到哪些地方,可以是类,方法,或者是属性上,定义在ElementType枚举中:
package java.lang.annotation;
public enum ElementType {
TYPE, /* 类、接口(包括注释类型)或枚举声明 */
FIELD, /* 字段声明(包括枚举常量) */
METHOD, /* 方法声明 */
PARAMETER, /* 形式参数声明 */
CONSTRUCTOR, /* 构造方法声明 */
LOCAL_VARIABLE, /* 局部变量声明 */
ANNOTATION_TYPE, /* 注释类型声明 */
PACKAGE, /* 包声明 */
TYPE_PARAMETER, /* 类型参数声明 @since 1.8*/
TYPE_USE /* 任何类型声明 @since 1.8*/
}
@Retention 作用是定义被它所注解的注解保留多久,一共有三种策略,定义在RetentionPolicy枚举中:
package java.lang.annotation;
public enum RetentionPolicy {
SOURCE, /* 注释将被编译器丢弃。*/
CLASS, /* 注释由编译器记录在类文件中,但不需要在运行时由VM保留。默认。*/
RUNTIME /*注释将由编译器记录在类文件中,并在运行时由VM保留,因此可以反射性地读取它们。*/
}
注解的处理
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Aspect
@Component
@Slf4j
public class VisitMetaAspect {
/**
* 声明切点
*/
@Pointcut("@annotation(com.shower.log.MyAnnotation)")
public void myPointCut() {
}
/**
* 环绕通知
*/
@Around("myPointCut()")
public Object aroundVisit(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] object = joinPoint.getArgs();
Object arg0 = object[0];
Object obj = null;
try {
system.out.print(arg0.toString());//逻辑处理
obj = joinPoint.proceed();
} catch (Throwable e) {
log.info(e.getMessage());
}
return obj;
}
@Before("myPointCut()")
public void doBeforeAdvice(JoinPoint joinPoint){
System.out.println("进入方法前执行.....");
}
/**
* 处理完请求,返回内容
* @param ret
*/
@AfterReturning(returning = "ret", pointcut = "myPointCut()")
public void doAfterReturning(Object ret) {
System.out.println("方法的返回值 : " + ret);
}
/**
* 后置异常通知
*/
@AfterThrowing("myPointCut()")
public void throwss(JoinPoint jp){
System.out.println("方法异常时执行.....");
}
/**
* 后置最终通知,final增强,不管是抛出异常或者正常退出都会执行
*/
@After("myPointCut()")
public void after(JoinPoint jp){
System.out.println("方法最后执行.....");
}
}
业务方法引入注解
@GetMapping("/info/{id}")
@MyAnnotation(descrption = "获取实体的信息")
public ResponseData info(@PathVariable("id") String id){
Entity entity = service.getById(id);
return ResponseData.ok(entity);
}
采用Controller包含的形式,不需要在目标方法上标识注解
@Aspect
@Component
public class LoginCheckAspect {
@Around(value = "execution(* com.mycontroller.*(..)) && " +
"execution(* com.mycontroller2.*(..))")
public Object check(ProceedingJoinPoint pjp) throws Throwable {
try {
BaseApi.checkLogin();
} catch (MyAppException e) {
throw new MyApiException(e.getMessage(),200);
}
return pjp.proceed();
}
}