乐趣区

关于springboot:SpringBoot基础之AOPAspectJ

日志切面,其中 execution 中能够革新为 @Before(“execution( (..))”),第一个 代表返回类型,第二个 代表办法名,括号中的点代表数个参数
JoinPoint 能够获取到执行的办法名称。@Before(“execution( hello())”) 示意带有一个任何类型并且返回参数不限的 hello 办法

@Component
@Aspect
public 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")
@EnableLoadTimeWeaving
public 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;
    }
}
退出移动版