当前位置: 首页 > 后端技术 > Java

基于SpringBoot的AOP&AspectJ

时间:2023-04-02 00:42:09 Java

Log方面,这里execution可以转化为@Before("execution((..))"),第一个代表返回类型,第二个代表方法名,括号里的点代表几个参数JoinPoint即可获取用于执行的方法名。@Before("execution(hello())")表示具有任何类型和无限返回参数的hello方法@Component@AspectpublicclassTracingAspect{Loggerlogger=Logger.getLogger("...");//execution可以在方法之前拦截,可以控制程序不进入方法@Before("execution(voiddoSomething())")//@Before("execution(**(..))")publicvoidentering(JoinPointjoinPoint){logger.info("进入方法"+joinPoint.getStaticPart().getSignature().toString());}//执行方法后可以拦截,获取结果、异常等@After("execution(**(..))")publicvoidexiting(JoinPointjoinPoint){logger.info("现有的"+joinPoint.getSignature());for(Objectorg:joinPoint.getArgs())logger.info("Arg:"+org);}//捕获异常@AfterThrowing(pointcut="execution(voidthrowsRuntimeException())",throwing="ex")publicvoidlogException(RuntimeExceptionex){logger.info("Exception:"+ex);}//捕获返回结果@AfterRe转向(切入点=“执行(**(..))”,返回=“字符串”)公共无效日志结果(字符串字符串){logger.info(“结果:”+字符串);}//也支持在进入方法之前,执行方法之后,捕获异常,捕获返回结果@Around("execution(**(..))")publicObjecttrace(ProceedingJoinPointproceedingJoinPoint)throwsThrowable{StringmethodInformation=proceedingJoinPoint.getStaticPart().getSignature().toString();logger.info("输入:"+methodInformation);尝试{返回proceedingJoinPoint.proceed();}catch(Throwableex){logger.info("Exceptionin:"+methodInformation+ex);扔前;最后{logger.info("退出"+methodInformation);}}}execution((..))表示在同一个包路径下//可以在执行中写绝对类名和方法名或者execute(intcom.test.Service.hello(int))//替换通过符号对应信息,其中..表示任意分包execution(*com.test..*Service.*(..))如果需要拦截注解//必须@Around("execution(@annotation.Trace**(..))")withmethodannotations//必须是@Around("exewithclassannotationscution(*(@org.springframework.stereotype.Repository*).*(..))")如果需要拦截注解类@Around("bean(*Service)")@Around("bean(*)")通过或者添加更多不同的拦截execution(*service.*.*(..))||execution(*repository.*.*(..))Pointcut可以替换原来的@Around("bean(*Service)")")//上下等价包com.pluralsight.mypointcuts;publicclassMyPointCusts{@Pointcut("bean(*Service)")publicvoidbeanNamePointcust(){}//表示类注解拦截@Pointcut("execution(*(@org.springframework.stereotype.Repository*).*(..))")publicvoidRepository(){}}@Around("com.pluralsight.mypointcuts.MyPointCusts.beanNamePointcust()")允许AspectJ动态加载EnableLoadTimeWeaving@Configuration@ComponentScan(basePackages="com.pluralsight")@EnableLoadTimeWeavingpublicclassSystemConfiguration{}Spring中定义了很多InterceptorCustomizableTraceInterceptor可以自定义跟踪输出SimpleTraceInterceptor获取基本信息DebugInterceptor获取完整信息PerformanceMonitorInterceptor使用Spring的StopWatch使用tiredness,可以用来衡量性能,可以精确到毫秒级,适合数据AsyncExecutionInterceptor允许异步方法调用,可以使用这个拦截器代替使用异步,并且该方法会在后台被其他线程执行ConcurrencyThrottleInterceptor可以限制对象中的线程数,实际可以设置和执行的线程数CatchInterceptor允许缓存方法调用结果,不需要自己写缓存重试机制@Around("execution(*com.pluralsight..*Service.*(..))")publicObjectretry(ProceedingJoinPointproceedingJoinPoint)throwsThrowable{try{returnproceedingJoinPoint.proceed();}catch(Throwableex){returnproceedingJoinPoint.proceed();}}Fus??e机制,在请求CircuitBreaker方法时,如果不处理可以正常返回,因为计数器为0,可以直接执行,但是当获取到异常时,将计数器的值设置为1,以便下次请求不会调用CircuitBreaker方法,只会增加计数器的值,判断直到计数器的值为10,再调用CircuitBreaker方法。如果成功将计数器设置为0,则可以继续调用它。如果有异常,同样将计数器设置为1,然后循环10次@Component@Aspect("perthis(com.pluralsight.aspect.CircuitBreakerAspect.circuitBreakerMethods())")@com.pluralsight.aspect.CircuitBreaker**(..))")publicvoidcircuitBreakerMethods(){}privateAtomicIntegercounter=newAtomicInteger();私有Throwable可抛出;@Around("com.pluralsight.aspect.CircuitBreakerAspect.circuitBreakerMethods()")publicObjectretry(ProceedingJoinPointproceedingJoinPoint)throwsThrowable{尝试{if(counter.get()==0){returnproceedingJoinPoint.proceed();}if(counter.incrementAndGet()==10){Objectresult=proceedingJoinPoint.proceed();counter.set(0);返回结果;}}catch(Throwablethrowable){this.throwable=throwable;counter.set(1);}throwthis.throwable;}}