#java #spring #aop #aspectj
#java #весна #aop #aspectj
Вопрос:
Я использую Spring AOP / AspectJ в моем Spring Boot API, чтобы создать аннотацию на Java, подобную @TrackExecutionTime
той, которую я могу использовать для любого метода, и она регистрирует общее время, необходимое для запуска метода. В настоящее время это работает в моей весенней загрузке. Моя проблема в том, что мой API получает доступ тысячи раз в день, и я хочу регистрировать какую-то другую уникальную информацию с этим временем выполнения, чтобы я мог отслеживать / отслеживать каждый запрос в своих журналах. Некоторые данные, которые я могу использовать, отправляются с телом запроса POST из JSON, но я не вижу, как передать эти аргументы в определение этой аннотации — кто-нибудь может помочь?
Я хочу передать некоторые аргументы (имя клиента, фамилия и т. Д.) Из этого объекта Customer, который является RequestBody, который клиент отправит в виде JSON в мой API в мой регистратор аннотаций:
@RestController
public class CustomersController implements CustomersApi {
@Autowired
private CustomerService customerService;
return ResponseEntity.ok(offersService.fetchCustomer(Customer, clientId));
}
Я определил конкретный класс и интерфейс для аннотации следующим образом. Именно здесь я хочу передать объект Customer, чтобы я мог зарегистрировать имя или фамилию:
@Aspect
@Component
@Slf4j
@ConditionalOnExpression("${aspect.enabled:true}")
public class ExecutionTimeAdvice {
@Around("@annotation(com.mailshine.springboot.aop.aspectj.advise.TrackExecutionTime)")
public Object executionTime(ProceedingJoinPoint point) throws Throwable {
long startTime = System.currentTimeMillis();
Object object = point.proceed();
long endtime = System.currentTimeMillis();
log.info("Class Name: " point.getSignature().getDeclaringTypeName() ". Method Name: " point.getSignature().getName() ". Time taken for Execution is : " (endtime-startTime) "ms");
return object;
}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TrackExecutionTime {
}
Ответ №1:
Вы можете попробовать добавить строку с нужным содержимым в аннотацию:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TrackExecutionTime {
String getContent() default "";
}
Используя его в методе:
@TrackExecutionTime(getContent = "something")
private static void someMethod(...)
а затем по совету проанализируйте это содержимое:
@Around("@annotation(myAnnotation)")
public Object executionTime(ProceedingJoinPoint point, TrackExecutionTime myAnnotation)throws Throwable {
...
String content = myAnnotation.getContent();
}
Ответ №2:
Это очень легко сделать; Я был тупицей, когда впервые опубликовал это, но вот ответ для тех, кто хочет сделать то же самое:
Когда вы создаете свой интерфейс, который определяет вашу аннотацию, используя Spring AOP / AspectJ, в вашем конкретном классе, как я перечислил выше, он имеет доступ ко всем аргументам, переданным вашему методу из объекта ProceedingJoinPoint . Таким образом, вы можете вызвать getArgs()
этот объект, чтобы получить все аргументы, переданные рассматриваемому методу при его запуске. Он вернет Object[], поэтому вам просто нужно будет выполнить несколько условных проверок, чтобы привести его к выбранному вами типу и убедиться, что он не пустой, чтобы вы не получили никаких исключений во время выполнения. Это полезно, если клиенты отправляют сообщения в ваш API, и вы хотите отслеживать время выполнения методов, но, возможно, у вас есть сотни / тысячи запросов, и вам нужно конкретно отследить, какие вызовы следуют по каким путям и что может замедлять работу вашего API… поэтому публикация дополнительных данных из RequestBody может быть полезной в ваших журналах…
например, я притворюсь, что отслеживаю какой-то метод, который принимает тип данных «Student», Который содержит кучу данных о студенте (имя, dob, средний балл и т. Д.). Таким образом, если у меня есть разные методы, которые запрашивают базу данных с помощью разных SQL-запросов на основе RequestBody, которые клиент отправляет в API, я могу зарегистрировать это, чтобы точно отследить, какие запросы замедляют работу моего API и их поток в моей кодовой базе и какие SQL-запросы они вызывают. т.е.
@Aspect
@Component
@Slf4j
@ConditionalOnExpression("${aspect.enabled:true}")
public class ExecutionTimeAdvice {
@Around("@annotation(com.mailshine.springboot.aop.aspectj.advise.TrackExecutionTime)")
public Object executionTime(ProceedingJoinPoint point) throws Throwable {
MyCustomStudentType student; // Class to hold Student data
String studentName = "";
Object[] argsArray = point.getArgs();
if (argsArray.length > 0 amp;amp; argsArray[0] instanceof MyCustomStudentType) {
student = (MyCustomStudentType) argsArray[0];
studentName = student.getName();
}
long startTime = System.currentTimeMillis();
Object object = point.proceed();
long endtime = System.currentTimeMillis();
// add the student name to your logs or any info you want to add with your
// execution time of your method, to make tracking your logs easier
log.info("Class Name: " point.getSignature().getDeclaringTypeName() ". Method Name: " point.getSignature().getName() ". Time taken for Execution is : " (endtime-startTime) "ms" ", for student name: " studentName);
return object;
}
}