springboot⾃定义注解及获取注解值注:⽹上搜集的内容,忘记留下出处,见谅
⾃定义注解
@Target(ElementType.METHOD) //定义是⽤在⽅法上
@Retention(RetentionPolicy.RUNTIME) // 定义是在运⾏时⽣效
public @interface ZlTest {
String param() default ""; //定义参数,默认为空
}
获取值
主要是⽅法参数多加⼀个注解类型的参数
/**
* 定义⼀个切⾯,⽤于统计指定注解的⽅法调⽤时间
*
* @author zl
* @ProjectName: MapDemo
* @create 2018-12-13 10:08
* @Version: 1.0
* <p>Copyright: Copyright (zl) 2018</p>
**/
@Component
@Aspect
@Slf4j
public class ZlAspect {
@Around("serviceStatistics(zlTest)")
public Object doAround(ProceedingJoinPoint joinPoint, ZlTest zlTest) throws Throwable {
System.out.println("beginning----");
/**
* 获取⽅法参数值
*/
String key = getKey(zlTest.param(), joinPoint);
log.info("参数是:{}",key);
/**
* 运⾏doSth(),执⾏⽅法的具体业务,并获取返回值,⽤⼀个Object类型来接收
*/
Object object = joinPoint.proceed();
/**
* 该⽅法的后置增强,可以修改返回值
*/
object = 10;
return object;
}
再来⼀个例⼦
@Documented//说明该注解将被包含在javadoc中
//@Retention: 定义注解的保留策略,
@Retention(RUNTIME)// 注解会在class字节码⽂件中存在,在运⾏时可以通过反射获取到
/
/@Target:定义注解的作⽤⽬标
@Target({METHOD,PARAMETER})// ⽅法和⽅法参数
@Inherited//说明⼦类可以继承⽗类中的该注解
public @interface LogAnnotation {
/**
* 如果注解只有⼀个属性,那么肯定是赋值给该属性。
* 如果注解有多个属性,⽽且前提是这多个属性都有默认值,那么你不写注解名赋值,会赋值给名字为“value”这属性。
* 如果注解有多个属性,其中有没有设置默认值的属性,那么当你不写属性名进⾏赋值的时候,是会报错的。
*/
//@AliasFor("")起别名
int value() default 000;
}
@Around(value = "LogAnnotation() && webLog() && @annotation(logAnnotation)")//环绕切点,在进⼊切点前,跟切点后执⾏ public Object doAround(ProceedingJoinPoint pjp, LogAnnotation logAnnotation)throws Throwable {
Object result = null;
// System.out.println("环绕。。。。。。1"+logAnnotation.value());
//接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestAttributes();
HttpServletRequest request = Request();
// 记录下请求内容
logger.info("URI : " + RequestURI());
logger.info("URL : " + RequestURL());
logger.info("HTTP_METHOD : " + Method());
logger.info("IP : " + RemoteAddr());
logger.info("CLASS_METHOD : " + Signature().getDeclaringTypeName() + "_" + Signature().getName()); logger.info("ARGS : " + Args()));
System.out.println("ARGS对象:" + Args()[0]);
}
详细介绍
import java.lang.annotation.*;
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TestAnnotation {
String value(); // 允许注解有参数
}
at.annotation.TestAnnotation;
at.annotation.TestAnnotation;
//import javassist.bytecode.SignatureAttribute;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.flect.MethodSignature;
import annotation.Order;
import org.springframework.stereotype.Component;
import flect.Method;
import flect.Method;
@Aspect // FOR AOPspringboot aop
@Order(-99) // 控制多个Aspect的执⾏顺序,越⼩越先执⾏, 当然也可以不写这注解, 对于写和不写@order的两个切⾯, 有@order的优先于⽆@order的执⾏; 都有@ord @Component
public class TestAspect {
// @Before可以有两者写法, @annotation(形参test)
@Before("@annotation(test)")
// 拦截被TestAnnotation注解的⽅法;如果你需要拦截指定package指定规则名称的⽅法,可以使⽤表达式execution(...),具体百度⼀下资料⼀⼤堆
// 因为参数传⼊了TestAnnotation ,所以会⾃动拦截@TestAnnotation 注解的
public void beforeTest(JoinPoint point, TestAnnotation test) throws Throwable {
System.out.println("beforeTest:" + test.name()); // 直接获取注解参数
}
@After("@annotation(test)")
public void afterTest(JoinPoint point, TestAnnotation test) {
System.out.println("afterTest:" + test.name()); // 直接获取注解参数
}
// 可以控制⽅法运⾏, 修改⼊参和返回值
@Around("@annotation(test)") // test表⽰aroundTest⽅法中的test⼊参
public Object aroundTest(ProceedingJoinPoint pjp, TestAnnotation test) throws Throwable {
System.out.println("afterTest:" + mq.value());
// 获取⼊参并修改
Object[] args = Args();
args[0] = "";
// 传⼊修改后的参数, 并继续执⾏
Object res = pjp.proceed(args);
// 修改返回值
String() + String();
}
/
*
// 指定切⾯
@Pointcut("@at.annotation.TestAnnotation)")
public void annotationPointCut() {
}
// @Before可以有两者写法, @annotation(函数名annotationPointCut)
@Before("annotationPointCut()")
public void before(JoinPoint joinPoint) {
MethodSignature sign = (MethodSignature) Signature();
Method method = Method();
TestAnnotation annotation = Annotation(TestAnnotation.class); // 获取指定注解实例
System.out.println("打印:" + annotation.value() + " 前置⽇志1"); // 获取注解实例的参数
}
@After("annotationPointCut()")
public void afterTTT(JoinPoint point) {
MethodSignature sign = (MethodSignature) Signature();
Method method = Method();
TestAnnotation annotation = Annotation(TestAnnotation.class); // 获取指定注解实例
System.out.println("打印⾃带参数:" + annotation.value() + " 后置⽇志1"); // 获取注解实例的参数
}
*/
}
@Around("@x.xxx.SystemLog)")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
SystemLog systemLog = ((Signature()).getMethod().getAnnotation(SystemLog.class);
......
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论