开发Springboot 自定义注解
在开发springboot项目中多多少少会需要用到自定义注解来实现某些业务,下面来说一下在springboot中开发自定义注解。
1.开发自定义注解需要的依赖
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
2.创建annotation(名字随意),然后创建注解类选择@Annotation
@Target:
@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
@Target:注解的作用目标
ElementType.TYPE——接口、类、枚举、注解
ElementType.FIELD——字段、枚举的常量
ElementType.METHOD——方法
ElementType.PARAMETER——方法参数
ElementType.CONSTRUCTOR)——构造函数
ElementType.LOCAL_VARIABLE——局部变量
ElementType.ANNOTATION_TYPE——注解
ElementType.PACKAGE——包
@Retention:注解的保留位置
RetentionPolicy.SOURCE:这种类型的Annotations只在源代码级别保留,编译时就会被忽略,在class字节码文件中不包含。
RetentionPolicy.CLASS:这种类型的Annotations编译时被保留,默认的保留策略,在class文件中存在,但JVM将会忽略,运行时无法获得。
RetentionPolicy.RUNTIME:这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
注解类里面的代码
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log
{
/**
* 内容
*/
public String title() default "";
}
3. 定义切面类
几个注解的解释
@Aspect 将一个类定义为一个切面类
@Around 环绕切点,在进入切点前,跟切点后执行
@After 在切点后,return前执行,
@Before 在切点前执行方法,内容为指定的切点
package com.demo.proxy;
import com.demo.annotation.Log;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
/**
* @ClassName : LogAspect
* @Description :
* @Author : 王道长
* @Date: 2020-08-14 10:54 //时间
*/
@Component
@Aspect
@Slf4j
public class LogAspect {
@Pointcut("@annotation(com.demo.annotation.Log)")
public void Log() {}
/**
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("Log()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
//获取拦截的方法相关信息
Signature signature = joinPoint.getSignature();
LogAspect.log.info("signature===={}",signature);
MethodSignature methodSignature = (MethodSignature) signature;
LogAspect.log.info("methodSignature===={}",methodSignature);
Object target = joinPoint.getTarget();
//获取访问 ip
String ip = InetAddress.getLocalHost().getHostAddress();
// 获取计算机名
String computername = InetAddress.getLocalHost().getHostName();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//操作系统
String operation = System.getProperty("os.name");
//为了获取注解信息
Method currentMethod = target.getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
LogAspect.log.info("currentMethod===={}",currentMethod);
//获取注解信息
Log log = currentMethod.getAnnotation(Log.class);
//获取注解内容
String litle= log.title();
}
@After("Log()")
public void after() {
System.out.println("after方法执行后");
}
}
4.controller 层
@Log(title = "填写需要的内容")
@GetMapping("log")
public String log(){
//写自己的业务
return "";
}