当前位置: 首页 > news >正文

临安建办网站建造师

临安建办网站,建造师,传媒公司招聘,为网站网站做宣传上一篇文章#xff0c;我们快速介绍了下spring-retry的使用技巧#xff0c;本篇我们将会剖析源码去学习 一、 EnableRetry注解 Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) EnableAspectJAutoProxy(proxyTargetClass false) Import(RetryConfiguration.c… 上一篇文章我们快速介绍了下spring-retry的使用技巧本篇我们将会剖析源码去学习 一、 EnableRetry注解 Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) EnableAspectJAutoProxy(proxyTargetClass false) Import(RetryConfiguration.class) Documented public interface EnableRetry {/*** Indicate whether subclass-based (CGLIB) proxies are to be created as opposed to* standard Java interface-based proxies. The default is {code false}.* return whether to proxy or not to proxy the class*/AliasFor(annotation EnableAspectJAutoProxy.class)boolean proxyTargetClass() default false;/*** Indicate the order in which the {link RetryConfiguration} AOP badvice/b should* be applied.* p* The default is {code Ordered.LOWEST_PRECEDENCE - 1} in order to make sure the* advice is applied before other advices with {link Ordered#LOWEST_PRECEDENCE} order* (e.g. an advice responsible for {code Transactional} behavior).*/int order() default Ordered.LOWEST_PRECEDENCE - 1;}英文翻译我就不再解释了上面说的很清楚这里重点提一下Import(RetryConfiguration.class)这个注解表明了EnableRetry注解的启动配置类是RetryConfiguration 通过Import注解来注入对应的配置类这样的做法同样可见于EnableAsync/EnableScheduling等注解上 看到这里如何定义一个Enable配置注解是不是会了呢~ 二、 RetryConfiguration如何构建 ponintCut和advisor SuppressWarnings(serial) Role(BeanDefinition.ROLE_INFRASTRUCTURE) Component public class RetryConfiguration extends AbstractPointcutAdvisorimplements IntroductionAdvisor, BeanFactoryAware, InitializingBean, SmartInitializingSingleton, ImportAware {//在这里构建了ponintCut和adviceOverridepublic void afterPropertiesSet() throws Exception {this.retryContextCache findBean(RetryContextCache.class);this.methodArgumentsKeyGenerator findBean(MethodArgumentsKeyGenerator.class);this.newMethodArgumentsIdentifier findBean(NewMethodArgumentsIdentifier.class);this.sleeper findBean(Sleeper.class);SetClass? extends Annotation retryableAnnotationTypes new LinkedHashSet(1);retryableAnnotationTypes.add(Retryable.class);//这里构建基于Retryable注解的切点this.pointcut buildPointcut(retryableAnnotationTypes);//这里构建了aop的通知this.advice buildAdvice();this.advice.setBeanFactory(this.beanFactory);if (this.enableRetry ! null) {setOrder(enableRetry.getNumber(order));}}}RetryConfiguration继承AbstractPointcutAdvisor实现了一个环绕切面通知的逻辑见AnnotationAwareRetryOperationsInterceptor的实现 这里需要补一下spring AOP的基础知识详情见文档 https://cloud.tencent.com/developer/article/1808649 我觉的这篇文章已经写的非常好了就不再细述 接下来我们重点关注 AnnotationAwareRetryOperationsInterceptor 的实现逻辑这里才是retgry启动业务的实现逻辑 三、AnotationAwareRetryOperationsInterceptor 重试retry逻辑的装配 我们看下它的核心实现 public class AnnotationAwareRetryOperationsInterceptor implements IntroductionInterceptor, BeanFactoryAware {//...省略其它代码Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {//这里获取代理MethodInterceptorMethodInterceptor delegate getDelegate(invocation.getThis(), invocation.getMethod());if (delegate ! null) {return delegate.invoke(invocation);}else {return invocation.proceed();}}/*** 拿到代理类的实现**private MethodInterceptor getDelegate(Object target, Method method) {//缓存解析结果主要用于class级别的retry配置ConcurrentMapMethod, MethodInterceptor cachedMethods this.delegates.get(target);if (cachedMethods null) {cachedMethods new ConcurrentHashMap();}MethodInterceptor delegate cachedMethods.get(method);if (delegate null) {MethodInterceptor interceptor NULL_INTERCEPTOR;Retryable retryable AnnotatedElementUtils.findMergedAnnotation(method, Retryable.class);if (retryable null) {retryable classLevelAnnotation(method, Retryable.class);}if (retryable null) {retryable findAnnotationOnTarget(target, method, Retryable.class);}if (retryable ! null) {//假如你需要实现自定义的拦截器那就走的是这里的逻辑例如你要实现retry的上下文放置到数据库里记录不放在内存里那你就要考虑这里作文章了if (StringUtils.hasText(retryable.interceptor())) {interceptor this.beanFactory.getBean(retryable.interceptor(), MethodInterceptor.class);}//有状态的retry, 走的是这里我没有深入研究stateful的应用场景总感觉即便是有状态的重试必然跟业务逻辑本身也强关联的那状态保护的逻辑肯定也会抽出来所以我不考虑放到框架本身去做毕竟不同业务状态保护方法不同else if (retryable.stateful()) {interceptor getStatefulInterceptor(target, method, retryable);}//这里应该是通用逻辑链路了else {interceptor getStatelessInterceptor(target, method, retryable);}}cachedMethods.putIfAbsent(method, interceptor);delegate cachedMethods.get(method);}this.delegates.putIfAbsent(target, cachedMethods);return delegate NULL_INTERCEPTOR ? null : delegate;}//无状态的重试拦截器private MethodInterceptor getStatelessInterceptor(Object target, Method method, Retryable retryable) {//这里基于注解生产重试策略 和 延迟策略RetryTemplate template createTemplate(retryable.listeners());template.setRetryPolicy(getRetryPolicy(retryable, true));template.setBackOffPolicy(getBackoffPolicy(retryable.backoff(), true));return RetryInterceptorBuilder.stateless().retryOperations(template).label(retryable.label())//这里关注下怎么构建recover的.recoverer(getRecoverer(target, method)).build();}//...省略其它代码 } 最终无状态的重试拦截器见所以RetryOperationsInterceptor是常用链路的实现逻辑 public static class StatelessRetryInterceptorBuilder extends RetryInterceptorBuilderRetryOperationsInterceptor {private final RetryOperationsInterceptor interceptor new RetryOperationsInterceptor();Overridepublic RetryOperationsInterceptor build() {if (this.recoverer ! null) {this.interceptor.setRecoverer(this.recoverer);}if (this.retryOperations ! null) {this.interceptor.setRetryOperations(this.retryOperations);}else {this.interceptor.setRetryOperations(this.retryTemplate);}if (this.label ! null) {this.interceptor.setLabel(this.label);}return this.interceptor;}private StatelessRetryInterceptorBuilder() {}}四、RetryOperationsInterceptor 常用retry operation的实现逻辑 RetryOperationsInterceptor是直接重试拦截器的实现逻辑它的逻辑比较简单封装了retryTemplate的执行逻辑核心代码见RetryOperationsInterceptor#invoke() Override public Object invoke(final MethodInvocation invocation) throws Throwable {//这个名字主要用于构建上下文的时候用正常有么有意义不大String name;if (StringUtils.hasText(this.label)) {name this.label;}else {name invocation.getMethod().toGenericString();}final String label name;//重试回调这里不作赘述RetryCallbackObject, Throwable retryCallback new MethodInvocationRetryCallbackObject, Throwable(invocation, label) {Overridepublic Object doWithRetry(RetryContext context) throws Exception {context.setAttribute(RetryContext.NAME, this.label);context.setAttribute(ARGS, new Args(invocation.getArguments()));/** If we dont copy the invocation carefully it wont keep a reference to* the other interceptors in the chain. We dont have a choice here but to* specialise to ReflectiveMethodInvocation (but how often would another* implementation come along?).*/if (this.invocation instanceof ProxyMethodInvocation) {context.setAttribute(___proxy___, ((ProxyMethodInvocation) this.invocation).getProxy());try {return ((ProxyMethodInvocation) this.invocation).invocableClone().proceed();}catch (Exception | Error e) {throw e;}catch (Throwable e) {throw new IllegalStateException(e);}}else {throw new IllegalStateException(MethodInvocation of the wrong type detected - this should not happen with Spring AOP, so please raise an issue if you see this exception);}}};//有recover的时候走这里就好if (this.recoverer ! null) {ItemRecovererCallback recoveryCallback new ItemRecovererCallback(invocation.getArguments(),this.recoverer);try {Object recovered this.retryOperations.execute(retryCallback, recoveryCallback);return recovered;}finally {RetryContext context RetrySynchronizationManager.getContext();if (context ! null) {context.removeAttribute(__proxy__);}}}//没有recover走这里都是调用RetryTemplate#execute的逻辑return this.retryOperations.execute(retryCallback);}至此全部的装配逻辑就讲结束流程看下来并不复杂对于未来自己想要定义一个类似的注解具有很大的参考意义下一篇我们讲解一下retry的真正的执行逻辑并对整体的设计做一个介绍和思考总结
http://www.zqtcl.cn/news/588937/

相关文章:

  • 定制网站开发冬天里的白玫瑰制作复杂的企业网站首页
  • 网站开发及设计演讲海报免费做网站app下载
  • 做动态图片的网站吗自考网站建设与实践
  • 建外贸网站需要多少钱胖咯科技 网站建设
  • wordpress注明网站做微网站的第三方登录
  • 学网站建设维护网站公司建设公司
  • 做小型网站的公司wordpress 主题上传
  • 网站之家查询重庆市建设项目环境申报表网站
  • 网站建设基础及流程网站运营一个月多少钱
  • 南沙免费网站建设wordpress邮箱注册
  • 网站关键字优化软件网络营销推广方式包括?
  • 专做装修的网站pc端好玩的大型网游
  • 洞泾网站建设网易考拉的网站建设
  • 网站建设的市场调研杭州网络公司项目合作
  • 济源网站制作电子商务平台有哪些
  • 网站轮播图怎么设计河南省住房城乡建设厅网站首页
  • o2o商城网站建设wordpress后台密码忘记了怎么办
  • 网站排版策划公司官网网站建设想法
  • 泉州网站建设报价建网站找哪家公司
  • 国外网站建设推广iapp网站怎么做软件
  • 网站的设计步骤做网站的虚拟机怎么用
  • 游戏的网站做普通网站多少钱
  • 单位门户网站建设苏州吴中区做网站公司
  • 新网站内部优化怎么做家电网站建设
  • 怎么看网站源码用什么做的wordpress 六亩填
  • 网站建设实习报告范文闵行区邮编
  • h5网站模板免费下载怎样制作专业简历
  • php网站语言切换功能如何做263邮箱入口
  • 电商网站及企业微信订烟专门做红酒的网站
  • 大庆商城网站建设微网站建设找哪家