uniapp开发app框架在提升开发效率中的独特优势与应用探索
1057
2022-12-15
使用spring aop 统一捕获异常和写日志的示例demo
之前给大家介绍过Spring AOP的基础知识,需要的朋友点击了解下吧,这边我将给您介绍用spring AOP 实现的异常捕获和日志的小demo,我也会详细解释相关配置。
首先给大家看一下我的工程目录:
大家可以先用eclipse中新建一个maven工程,在工程中pom.xml按下面文件添加依赖:
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
添加完依赖后,开始配置web.xml文件,如下:
/WEB-INF/config/applicationContext.xml
//这边是加载spring的配置文件
配置完web.xml后,你可开始配置spring配置文件了,也就是applicationContext.xml文件。如下:
xmlns:context="http://springframework.org/schema/context" xmlns:aop="http://springframework.org/schema/aop" xmlns:tx="http://springframework.org/schema/tx" xmlns:jpa="http://springframework.org/schema/data/jpa" xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans-4.0.xsd http://springframework.org/schema/context http://springframework.org/schema/context/spring-context-4.0.xsd http://springframework.org/schema/tx http://springframework.org/schema/tx/spring-tx-4.0.xsd http://springframework.org/schema/data/jpa http://springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://springframework.org/schema/aop http://springframework.org/schema/aop/spring-aop-4.0.xsd" default-lazy-init="true">
xmlns:context="http://springframework.org/schema/context" xmlns:aop="http://springframework.org/schema/aop"
xmlns:tx="http://springframework.org/schema/tx" xmlns:jpa="http://springframework.org/schema/data/jpa"
xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans-4.0.xsd
http://springframework.org/schema/context http://springframework.org/schema/context/spring-context-4.0.xsd
http://springframework.org/schema/tx http://springframework.org/schema/tx/spring-tx-4.0.xsd
http://springframework.org/schema/data/jpa http://springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://springframework.org/schema/aop http://springframework.org/schema/aop/spring-aop-4.0.xsd"
default-lazy-init="true">
然后配置spring-mvc-config.xml文件,如下:
xmlns:context="http://springframework.org/schema/context" xmlns:mvc="http://springframework.org/schema/mvc" xmlns:aop="http://springframework.org/schema/aop" xsi:schemaLocation="http://springframework.org/schema/mvc http://springframework.org/schema/mvc/spring-mvc-4.0.xsd http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans-4.0.xsd http://springframework.org/schema/context http://springframework.org/schema/context/spring-context-4.0.xsd http://springframework.org/schema/aop http://springframework.orqhZDeEg/schema/aop/spring-aop-4.0.xsd ">
xmlns:context="http://springframework.org/schema/context" xmlns:mvc="http://springframework.org/schema/mvc"
xmlns:aop="http://springframework.org/schema/aop"
xsi:schemaLocation="http://springframework.org/schema/mvc http://springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans-4.0.xsd
http://springframework.org/schema/context http://springframework.org/schema/context/spring-context-4.0.xsd
http://springframework.org/schema/aop http://springframework.orqhZDeEg/schema/aop/spring-aop-4.0.xsd ">
上面spring容器和spring-mvc容器中扫描的类不一样,是为了区分两个容器的职责,spring-mvc负责controller控制器这块的类。因为我们的异常捕获是从controller类往外抛,所以我们对于aspect类也放在spring-mvc容器中。
下面就开始介绍我们的切面类:
package com.zy.test.aspect;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import com.zy.test.annotation.ArchivesLog;
/**
* web 异常切面
* @author user
*
*/
@Aspect
public class WebExceptionAspect {
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")//连接点是@RequestMapping注解的方法
private void webPointcut() {}
@AfterThrowing(pointcut = "webPointcut()", throwing = "e")//切点在webpointCut()
public void handleThrowing(JoinPoint joinPoint, Exception e) {//controller类抛出的异常在这边捕获
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
//开始打log
System.out.println("异常:" + e.getMessage());
System.out.println("异常所在类:" + className);
Shttp://ystem.out.println("异常所在方法:" + methodName);
System.out.println("异常中的参数:");
System.out.println(methodName);
for (int i = 0; i < args.length; i++) {
System.out.println(args[i].toString());
}
}
@Before("execution(* com.zy.test.controller.*.*(..))")
public void beforeProcess(JoinPoint joinPoint) {
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
//在项目中最好记录当前操作的时间和用户
System.out.println("操作所在类:" + className);
System.out.println("操作所在方法:" + methodName);
System.out.println("操作中的参数:");
for (int i = 0; i < args.length; i++) {
System.out.println(args[i].toString());
}
}
@AfterReturning(value = "execution(* com.zy.test.controller.*.*(..)))", returning = "returnVal")
public void returnProcess(JoinPoint joinPoint, Object returnVal) {
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
Class targetClass = null;
String operationName = "";
try {
targetClass = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Method[] methods = targetClass.getMethods();
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs != null && clazzs.length == args.length&&
method.getAnnotation(ArchivesLog.class)!=null) {//这块是取出我们注解ArchiveLog中的值,一遍在日志时明确这个操作的名称
operationName = method.getAnnotation(ArchivesLog.class).operationName();
break;
}
}
}
System.out.println("操作名称:" + operationName);
System.out.println("方法正常返回的值:" + returnVal);
}
}
这边我们需要自定义注解:
package com.zy.test.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
@Target({ElementType.PARAMETER, ElementType.METHOD}) //注解可以用于参数或者方法上
@Retention(RetentionPolicy.RUNTIME) //保留至运行时
@Documented//被javadoc所记录
public @interface ArchivesLog {
/**
* 操作类型
@return
*/
public String operationType() default "";
/**
* 操作名称
@return
*/
public String operationName() default "";
}
然后定义我们的controller类:
package com.zy.test.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.zy.test.annotation.ArchivesLog;
import com.zy.test.service.ExceptionService;
@Controller
@RequestMapping("/exception")
public class ExceptionController {
@Autowired
private ExceptionService service;
@RequestMapping(value = "/test/{id}", method = RequestMethod.GET, produces = "application/json;charset=UTF-8" )
@ResponseBody
@ArchivesLog(operationType = "测试", operationName = "测试异常或者测试返回")
public JSONObject test(@PathVariable Integer id) throws Exception {
JSONObject result = new JSONObject();
result.put("zhouyu", "asdasdasdasd");
// try {//去掉注释可以测捕获的异常,不去掉注释可以测日志处理
// service.test();
// } catch (Exception ex) {
// throw new Exception("controller 层 异常");
// }
return result;
}
}
service接口:
package com.zy.test.service;
public interface ExceptionServiceBase {
void test() throws Exception;
}
service实现类:
package com.zy.test.service;
import org.springframework.stereotype.Service;
@Service
public class ExceptionService implements ExceptionServiceBase{
public void test() throws Exception {
boolean flag = true;
if(flag) {
throw new Exception("service 异常");
}
}
}
其中工程中的ExceptionConfig是一个配置类,用于扫描包的。但是如果你是用配置文件的化,这个文件就不用了,这边就不说了。
github上可以拉到新代码:代码在这里
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~