使用Spring AOP是一种非常方便的方式,可以实现对异常和日志的统一处理。下面是使用Spring AOP实现统一处理异常和打印日志的完整攻略。
1. 异常处理
1.1 创建异常类
首先需要创建一个自定义异常类,例如:
public class MyException extends RuntimeException {
public MyException(String message) {
super(message);
}
}
1.2 创建异常处理器
创建一个异常处理器,用于处理系统中发生的异常。例如:
@Component
@Aspect
public class ExceptionHandler {
@ExceptionHandler(MyException.class)
public void handleMyException(MyException e) {
// 处理异常
System.out.println("发生了自定义异常: " + e.getMessage());
}
@ExceptionHandler(Exception.class)
public void handleException(Exception e) {
// 处理异常
System.out.println("发生了异常: " + e.getMessage());
}
}
在这个例子中,ExceptionHandler使用了Spring的@Aspect注解,表明它是一个切面,同时也使用了@Component注解,表明它应该被Spring框架扫描并实例化。
@ExceptionHandler注解定义了哪些异常该方法可以处理,我们可以指定自定义异常类,也可以定义一个处理所有异常的方法。
1.3 在切面中引用异常处理器
在切面中通过@DeclareParents注解引用异常处理器,例如:
@Component
@Aspect
public class ServiceAspect {
@DeclareParents(value = "com.example.demo.service.*",
defaultImpl = ExceptionHandler.class)
private ExceptionHandler handler;
// ...
}
在这个例子中,ServiceAspect使用了Spring的@Aspect注解,表明它是一个切面,我们使用@DeclareParents注解来引用ExceptionHandler。
@DeclareParents注解的value属性指定了ServiceAspect切面要对哪个类创建代理,defaultImpl属性指定了默认的异常处理器实现类(就是上面创建的ExceptionHandler类)。
1.4 抛出异常
在ServiceAspect的切点方法中抛出异常,例如:
@Service
public class UserService {
public void addUser(String name) {
if (name == null || name.equals("")) {
// 抛出自定义异常
throw new MyException("用户名不能为空");
}
// ...
}
}
在这个例子中,在UserService类的addUser方法中,如果name为空,就会抛出自定义的MyException异常。
1.5 测试
运行测试用例:
@SpringBootTest
class DemoApplicationTests {
@Autowired
UserService userService;
@Test
void testAddUser() {
// 添加用户,用户名为空
userService.addUser(null);
}
}
如果一切正常,你会看到打印日志:"发生了自定义异常: 用户名不能为空"。这表明已经成功地处理了自定义异常。
2. 日志处理
2.1 创建日志处理器
创建一个日志处理器,用于打印日志。例如:
@Component
@Aspect
public class LoggingHandler {
@Before("execution(* com.example.demo.service.UserService.addUser(..)) && args(name)")
public void logBefore(String name) {
// 打印日志
System.out.println("添加用户:" + name);
}
@AfterReturning("execution(* com.example.demo.service.UserService.addUser(..))")
public void logAfterReturning() {
// 打印日志
System.out.println("用户添加成功");
}
@AfterThrowing("execution(* com.example.demo.service.UserService.addUser(..))")
public void logAfterThrowing() {
// 打印日志
System.out.println("用户添加失败");
}
}
在这个例子中,LoggingHandler使用了Spring的@Aspect注解,表明它是一个切面,同时也使用了@Component注解,表明它应该被Spring框架扫描并实例化。
@Before注解表示在执行addUser方法之前打印日志,@AfterReturning注解表示在addUser方法成功执行后打印日志,@AfterThrowing注解表示在执行addUser方法失败时打印日志。
2.2 在切面中引用日志处理器
在切面中通过@DeclareParents注解引用日志处理器,例如:
@Component
@Aspect
public class ServiceAspect {
@DeclareParents(value = "com.example.demo.service.*",
defaultImpl = LoggingHandler.class)
private LoggingHandler handler;
// ...
}
在这个例子中,ServiceAspect使用了Spring的@Aspect注解,表明它是一个切面,我们使用@DeclareParents注解来引用LoggingHandler。
@DeclareParents注解的value属性指定了ServiceAspect切面要对哪个类创建代理,defaultImpl属性指定了默认的日志处理器实现类(就是上面创建的LoggingHandler类)。
2.3 测试
运行测试用例:
@SpringBootTest
class DemoApplicationTests {
@Autowired
UserService userService;
@Test
void testAddUser() {
// 添加用户
userService.addUser("张三");
}
}
如果一切正常,你会看到打印日志:"添加用户:张三"和"用户添加成功"。这表明已经成功地实现了日志打印。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用spring aop统一处理异常和打印日志方式 - Python技术站