Recently, I am working on an iot project, an IoT project that connects the devices at home and in the community to the cloud. The project is very large and has been service-oriented. Each module has been extracted into independent services, and the services communicate through HSF. I'm mostly responsible for the homeLink interface. When I got the project, I found that all the exceptions in the project were thrown and not processed. Is it necessary to catch exceptions when others call? Later, when debugging an interface, I found out through debug: the original project uses aspect as aspect, and handles exceptions uniformly.
code:
@Aspect
@Component
public class HsfAspect {
private static final Logger logger_hsf = LoggerFactory.getLogger(LogFileEnum.HSF_SERVICE.getName());
private static final Logger logger_error = LoggerFactory.getLogger(LogFileEnum.ERROR.getName());
@Pointcut("execution(public * com.netease.iotx.service.hsf.provider..*.*(..))")
public void hsfLog() {}
@Around("hsfLog()")
public Object logFun(ProceedingJoinPoint joinPoint) {
Long startTime = System.currentTimeMillis();
Object result = null;
Throwable exception = null;
try {
result = joinPoint.proceed();
return result;
} catch (IoTxException e) {
result = new IoTxResult<>(e.getCode(), e.getMessage());
return result;
} catch (Throwable throwable) {
//error日志打印出堆栈,方便排查问题.
logger_error.error("UNEXPECTED ERROR: [INTERFACE : {}], [METHOD : {}], [ARGS : {}], EXCEPTION : ",
joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(),
joinPoint.getArgs(),
throwable);
exception = throwable;
return new IoTxResult<>(IoTxCodes.SERVER_ERROR);
} finally {
long timeSpend = System.currentTimeMillis() - startTime;
if (exception != null) {
logger_hsf.error("[INTERFACE : {}], [METHOD : {}], [ARGS : {}], [EXCEPTION : {}], [SPEND TIME : {}]",
joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(),
joinPoint.getArgs(),
exception.getMessage(),
timeSpend);
}
if (result != null) {
String resultdata = null;
if (result instanceof IoTxResult) {
Object data = ((IoTxResult)result).getData();
resultdata = (data != null) ? data.toString() : "";
}
logger_hsf.info("[INTERFACE : {}], [METHOD : {}], [ARGS : {}], [RESULT : {}], [RESULT_DATA : {}], [SPEND TIME : {}]",
joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(),
joinPoint.getArgs(),
result.toString(),
resultdata,
timeSpend);
}
}
}
}
After checking some information, the AOP annotations used by Spring are divided into three levels:
the precondition is to configure <aop:aspectj-autoproxy proxy-target-class=”true”/> in xml
- @Aspect is placed on the class header to treat the class as an aspect.
- @Pointcut is placed on the method header and defines a pointcut expression that can be referenced by other methods.
- 5 types of notifications
- @Before, before notice, on the method header.
- @After, post [finally] notification, on the method header.
- @AfterReturning, post the [try] notification, put it on the method header, and use returning to refer to the method return value.
- @AfterThrowing, post [catch] notification, put it on the method header, use throwing to refer to the thrown exception.
- @Around, surround notification, placed in the method header, this method determines whether the real method is executed, and must have a return value.