一.项目pom.xml文件引入切面依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
二.定义注解类
import java.lang.annotation.*;
/**
* @desc 错误日志注解
* @author lss
*/
@Target(ElementType.METHOD) //应用于方法上面
@Retention(RetentionPolicy.RUNTIME) //表示在运行时注解任可用
@Documented
public @interface ErrorLog {
/**
* 日志报错类型
*/
String type() default "";
String centralId() default "setCentralId";
}
注解:
@Target
- @Target 说明了Annotation所修饰的对象范围
- 取值(ElementType)有:
- 1.CONSTRUCTOR:用于描述构造器
- 2.FIELD:用于描述域
- 3.LOCAL_VARIABLE:用于描述局部变量
- 4.METHOD:用于描述方法
- 5.PACKAGE:用于描述包
- 6.PARAMETER:用于描述参数
- 7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Retention
-
@Retention定义了该Annotation被保留的时间长短:
-
某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对Annotation的“生命周期”限制。
-
取值(RetentionPoicy)有:
-
1.SOURCE:在源文件中有效(即源文件保留)
-
2.CLASS:在class文件中有效(即class保留)
-
3.RUNTIME:在运行时有效(即运行时保留)
@Documented
- @Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
三.定义切面类,实现方法拦截和异常处理逻辑
import com.qike.sys.annotation.ErrorLog;
import com.qike.sys.service.ErrorResponseService;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
@RequiredArgsConstructor
public class ErrorLogAspect {
//切点
@Around("@annotation(errorLog)")
public Object around(ProceedingJoinPoint joinPoint, ErrorLog errorLog) throws Throwable {
// 在方法执行前做些事情
System.out.println("Before method execution...");
try {
// 执行被拦截的方法
Object result = joinPoint.proceed();
// 在方法执行后做些事情
System.out.println("After method execution...");
return result;
} catch (Exception e) {
// 记录错误信息
// 注解自定义属性获得值
String type = errorLog.type;
// 异常逻辑处理
...
System.out.println("Error occurred: " + e.getMessage());
throw e;
}
}
}
注解:
@Aspect
- @Aspect:作用是把当前类标识为一个切面供容器读取
@Component
- @Component:注解用于标记一个类,该类充当Spring应用程序上下文中的组件;
三.定义切面类,实现对象存入值
@Aspect
@Component
@RequiredArgsConstructor
public class ErrorLogAspect {
//切点
@Around("@annotation(errorLog)")
public Object around(ProceedingJoinPoint joinPoint, ErrorLog errorLog) throws Throwable {
// 获取他们的目标对象信息
Object[] paramValues = joinPoint.getArgs();
// 获取所有请求的参数名称
String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
// 参数名和对象信息匹配
Object dto = null;
for (int i = 0; i < paramNames.length; i++) {
if(sendDataInfo.value().equals(paramNames[i])){
dto = paramValues[i];
}
}
// 自己根据需求处理信息,例如获取centralId存入对象
String centralId = "12";
......
// 封装进对象参数
try{
Method[] methods = dto.getClass().getMethods();
for(Method m: methods){
if(m.getName().equals(errorLog.centralId())){
if(ObjectUtil.isNotEmpty(centralId)){
m.invoke(dto,centralId);
}
}
}
}catch (Exception e){e.printStackTrace();}
//放行调用目标方法
Object proceed = joinPoint.proceed();
//返回值就是controller的返回值
System.out.println("proceed = " + proceed);
return proceed;
}
}
四.在方法中使用文章来源:https://www.toymoban.com/news/detail-738549.html
@ErrorLog(type = "2")
public void splitLogTable(){
}
四.在拦截器中使用文章来源地址https://www.toymoban.com/news/detail-738549.html
@Slf4j
@Component
public class AppControllerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod) handler;
try {
log.debug(request.getServletPath());
// 不用登录的标识
ErrorLog loginRestrict = handlerMethod.getMethodAnnotation(ErrorLog.class);
// 未登录可以访问
if (null != loginRestrict) {
return true;
}
......
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
到了这里,关于Spring Boot面向切面加注解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!