我正在撰寫一個 Spring Boot 應用程式。我想用我的注釋審核方法@AuditMetod:例如我有foo()帶有注釋的方法:
@AuditMetod(name = "SomeValue")
foo() {...}
我想處理和審計這樣的方法(最簡單的例子):
auditMethod(Method method) {
if (method.hasAnnotation(AuditMethod.class)) {
System.out.println (method.getName() " was called at " new Date())
}
}
更新
感謝@Karthikeyan @Swapnil Khante 和@misha2048 我明白了,我需要使用AOP。但我有兩個問題:
- Aspect 類中唯一沒有被呼叫的方法,我在日志中看不到“----------ASPECT METHOD IS CALLED---------”字樣
- 我如何在方面方法中檢查它正在攔截什么方法。獲取 Method 類的實體。
現在我有以下代碼:控制器:
@PostMapping
@LoggingRest(executor = "USER", method = "CREATE", model = "SUBSCRIPTION")
public ResponseEntity<?> create(@Valid @RequestBody SubscriptionRequestDto dto) {
...
}
方面:
`@Aspect
@Slf4j
@Component
public class AuditAspect {
@Pointcut(value = "@annotation(com.aspect.annotations.LoggingRest)")
public void auditMethod(ProceedingJoinPoint proceedingJoinPoint) {
log.info("----------ASPECT METHOD IS CALLED------------");
}`
和注釋:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LoggingRest {
String executor() default "SYSTEM";
String method() default "";
String model() default "";
}
uj5u.com熱心網友回復:
審計是一個cross-cutting問題,可以使用 AOP 來處理。
Spring interceptor另一種解決方案是通過撰寫自定義注釋并使用 a來撰寫業務邏輯來使用低級解決方案。
要使用,Spring interceptor您需要實作HandlerInterceptor interface
注釋示例
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Audit {
boolean active() default true;
}
攔截器示例
@Component
public class AuditInterceptor implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Audit annotation = handlerMethod.getMethodAnnotation(Audit.class);
if (annotation != null && annotation.active()) {
// your business logic
}
}
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
檢查這個攔截器示例
uj5u.com熱心網友回復:
正如@Karthikeyan 提到的,我認為這里的解決方案之一是使用 Spring AOP。
如果你不知道一個簡單的介紹 - spring-aop 模塊實作了面向方面的編程范式。我們提取了一些常見的功能,我們通常希望將其應用于函式/方法的某個子集,應用于一個名為的物體Aspect(請參閱用 注釋的類@Aspect)。此類將包含橫切功能 - 例如審核,例如我們要審核方法執行時間,比如說。我們只是把要執行的代碼,條件,告訴 spring 哪些確切的 bean 方法應該受到這方面的影響,見下文。
例如,如果我可以使用以下非常簡單的示例來審核方法執行持續時間(在我的情況下,我說任何public方法,回傳void到 Classcom.example.stackoverflow.BusinessLogicClass中都必須通過此 Aspect 進行檢查):
@SpringBootApplication
@EnableAspectJAutoProxy
public class StackoverflowApplication implements ApplicationRunner {
@Autowired
private BusinessLogicClass businessLogicClass;
public static void main(String[] args) {
SpringApplication.run(StackoverflowApplication.class, args);
}
@Override
public void run(ApplicationArguments args) throws Exception {
businessLogicClass.test();
}
}
@Aspect
@Component
class MyAspectLogicClass {
@Around("execution(public void com.example.stackoverflow.BusinessLogicClass.*(..))")
public Object hangAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long before = System.currentTimeMillis();
Object returnedValue = proceedingJoinPoint.proceed();
long after = System.currentTimeMillis();
System.out.printf("Retruned in '%s' ms %n", (after - before));
return returnedValue;
}
}
@Component
class BusinessLogicClass {
public void test() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在我的情況下,我將獲取方法執行前的時間,然后通過 呼叫progressingJoinPoint.proceed()將執行委托給真正的方法,然后,一旦我得到回應,我將獲得當前系統時間并計算執行時間,相當簡單。
我希望我至少已將您指引到某個地方,如果您正在尋找檔案,我建議您應該尋找以下資源:
- https://docs.spring.io/spring-framework/docs/2.5.x/reference/aop.html 官方spring doc(有點陳舊,但有一些有價值的東西需要學習)
- https://docs.spring.io/spring-framework/docs/4.3.15.RELEASE/spring-framework-reference/html/aop.html是更新鮮的檔案
希望它有所幫助:)
uj5u.com熱心網友回復:
問題出在正確的注釋中。在 Aspect 課程中,我嘗試過@Around,一切都按我的需要進行。
@Aspect
@Slf4j
@Component
public class AuditAspect {
@Around(value = "@annotation(com.aspect.annotations.LoggingRest)")
public void auditMethod(ProceedingJoinPoint proceedingJoinPoint) {
var method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
log.info("----------ASPECT METHOD IS CALLED------------");
}
}
為了獲取 Method 實體,我使用了閑置代碼
Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/485758.html
