日志切面,其中execution中能够革新为@Before("execution( (..))"),第一个代表返回类型,第二个代表办法名,括号中的点代表数个参数
JoinPoint能够获取到执行的办法名称。@Before("execution( hello())")示意带有一个任何类型并且返回参数不限的hello办法
@Component@Aspectpublic class TracingAspect { Logger logger = Logger.getLogger("..."); //执行办法前能够截获,能够控制程序不进入办法 @Before("execution(void doSomething())") //@Before("execution(* *(..))") public void entering(JoinPoint joinPoint){ logger.info("entering method"+joinPoint.getStaticPart().getSignature().toString()); } //执行办法后能够截获,能够获取到后果,异样等 @After("execution(* *(..))") public void exiting(JoinPoint joinPoint){ logger.info("existing "+joinPoint.getSignature()); for(Object org:joinPoint.getArgs()) logger.info("Arg: "+org); } //捕捉异样 @AfterThrowing(pointcut = "execution(void throwsRuntimeException())", throwing = "ex") public void logException(RuntimeException ex){ logger.info("Exception:" + ex); } //捕捉返回后果 @AfterReturning(pointcut = "execution(* *(..))", returning = "string") public void logResult(String string){ logger.info("result:" + string); } //同时反对进入办法前,执行办法后,捕捉异样,捕捉返回后果 @Around("execution(* *(..))") public Object trace(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{ String methodInformation = proceedingJoinPoint.getStaticPart().getSignature().toString(); logger.info("Entering:"+methodInformation); try{ return proceedingJoinPoint.proceed(); }catch(Throwable ex){ logger.info("Exception in:"+methodInformation + ex); throw ex; }finally { logger.info("Exiting "+methodInformation); } }}
execution( (..))示意同一个package门路下
//能够在execution中写好相对的类名办法名称也可execution(int com.test.Service.hello(int))//通过符号替换相应的信息,其中..示意任何子包 execution(* com.test..*Service.*(..))
如果须要截取带注解的
//必须是带办法注解的@Around("execution(@annotation.Trace * *(..))")//必须是带类注解的@Around("execution(* (@org.springframework.stereotype.Repository *).*(..))")
如果须要截取带注解的类
@Around("bean(*Service)")@Around("bean(*)")
通过或者来多减少不同的截取
execution(* service.*.*(..))||execution(* repository.*.*(..))
Pointcut能够替换原有的
@Around("bean(*Service)")//下面与上面的等价package com.pluralsight.mypointcuts;public class MyPointCusts { @Pointcut("bean(*Service)") public void beanNamePointcust(){} //示意类注解截获 @Pointcut("execution(* (@org.springframework.stereotype.Repository *).*(..))") public void Repository(){}}@Around("com.pluralsight.mypointcuts.MyPointCusts.beanNamePointcust()")
容许AspectJ动静加载EnableLoadTimeWeaving
@Configuration@ComponentScan(basePackages = "com.pluralsight")@EnableLoadTimeWeavingpublic class SystemConfiguration {}
还有很多Spring曾经定义好的Interceptor
CustomizableTraceInterceptor可自定义跟踪输入
SimpleTraceInterceptor获取根本信息
DebugInterceptor获取残缺信息
PerformanceMonitorInterceptor应用StopWatch的Spring应用累,可用于测量性能,能够准确到毫秒级,实用于数据
AsyncExecutionInterceptor容许异步办法调用,能够应用这个拦截器而不必应用异步,并且办法将有后盾中的其余线程执行
ConcurrencyThrottleInterceptor能够限度对象中的线程数,理论能够设置并执行的线程数
CatchInterceptor容许缓存办法的调用后果,不须要编写本人的缓存
重试机制
@Around("execution(* com.pluralsight..*Service.*(..))")public Object retry(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { try { return proceedingJoinPoint.proceed(); } catch (Throwable ex) { return proceedingJoinPoint.proceed(); }}
熔断机制,当申请CircuitBreaker的办法时,如果能够失常返回不做解决,因为counter就是0,能够间接执行
然而当获取到异样时,设置counter值为1,这样下一次再来申请则不会调用CircuitBreaker的办法,只会减少counter的值,并判断
直到counter的值为10,则调用CircuitBreaker的办法,如果胜利设置counter为0能够持续调用,如果异样同样设置counter为1,再循环10次
@Component@Aspect("perthis(com.pluralsight.aspect.CircuitBreakerAspect.circuitBreakerMethods())")public class CircuitBreakerAspect { @Pointcut("execution(@com.pluralsight.aspect.CircuitBreaker * *(..))") public void circuitBreakerMethods(){} private AtomicInteger counter = new AtomicInteger(); private Throwable throwable; @Around("com.pluralsight.aspect.CircuitBreakerAspect.circuitBreakerMethods()") public Object retry(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{ try{ if(counter.get() == 0){ return proceedingJoinPoint.proceed(); } if(counter.incrementAndGet() == 10) { Object result = proceedingJoinPoint.proceed(); counter.set(0); return result; } }catch(Throwable throwable){ this.throwable = throwable; counter.set(1); } throw this.throwable; }}