网站是怎样建立的流程是什么个人博客系统毕业设计论文
网站是怎样建立的流程是什么,个人博客系统毕业设计论文,网站开发算法,百度网站做不做转载自 一次动态代理的填坑之旅
背景
想在现有的接口加上熔断降级或者限流的功能#xff0c;比较好的方式是通过注解的方式#xff0c;并基于动态代理进行实现#xff0c;下面代码是Rhino的实现
Rhino
public class ServiceImpl {Degrade(rhinoKey syncMethod-0比较好的方式是通过注解的方式并基于动态代理进行实现下面代码是Rhino的实现
Rhino
public class ServiceImpl {Degrade(rhinoKey syncMethod-0, fallBackMethod fallbackMethod)public void method() throws Exception {int i 1 / 0;}private String fallbackMethod() throws Exception {return fallback;}}
通过在方法添加Degrade注解很方便的赋予了method方法熔断降级功能在该方法的失败率达到阈值时就自动熔断并调用降级方法。
这里的动态代理并没有使用Spring的AOP而是自己实现了 BeanPostProcessor和 BeanFactoryPostProcessor接口另外也实现了 PriorityOrdered接口。
在生成动态代理对象的时候根据类是否有实现接口选择使用JDK的Proxy还是使用Cglib。
/**
* param clazz
* param origin
* return
*/private static Object createProxyService(Class clazz, Object origin) {Object proxy;if (clazz.getInterfaces().length 0) {proxy Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new RhinoInvocationHandler(origin, clazz));} else {Enhancer enhancer new Enhancer();enhancer.setSuperclass(clazz);enhancer.setCallback(new RhinoInvocationHandler(origin, clazz));proxy enhancer.create();}return proxy;
} 这样的实现在99%的情况下是没有问题的直到有一天有两个业务同时反馈了一个问题使用了熔断降级的注解之后发现自身的Spring AOP注解失效了或者是直接启动异常WTF这个问题一直都没考虑过好吗...
为什么会这样Spring AOP到底干了什么或者是自己的注解到底有什么问题
复现问题
为了快速定位问题并解决问题最好的办法就是复现该问题写了一个简单的Spring AOP的例子。
Component //加入到IoC容器
Aspect //指定当前类为切面类
public class Aop {Pointcut(execution(* com.dianping.rhino.aop.*.*(..)))public void pointCut(){}Before(pointCut())public void begin(){System.out.println(begin);}After(pointCut())public void close(){System.out.println(close);}Around(value annotation(MethodLog))public void around() {System.out.println( MethodLog );}
}
这里简短的解释下Spring AOP各个注解的作用 Aspect切面标识该类是一个切面类 Pointcut切入点用来标识哪些方法是需要被添加切面的 Before在切入点执行方法之前进行增强 After在切入点执行方法之后进行增强 Around在该例子中只有添加了MethodLog注解的方法才会被增强
一切准备就绪开启DEBUG之旅Spring的内部逻辑有点复杂整个过程需要一点耐心。 通过Debug发现Rhino的代理对象Processor排在Spring AOP的Processor意味着Rhino生成的代理对象会传给Spring AOP的Processor再做一层代理在Spring AOP生成代理对象的内部逻辑中有这么一段判断逻辑。 在createProxy方法中会根据传入的beanClass即上一个Processor处理过的对象判断是否有实现接口。
回到Rhino的实现因为ServiceImpl类没有实现接口所以内部会采用CGLIB的方式创建代理对象我们来看下这个对象的接口。 好家伙默默的给加了一个Factory接口这样在Spring AOP的处理中就当做有接口的情况进行实现了。这里最大的问题是最终生成的代理对象是Factory类型的对象在赋值给ServiceImpl变量时就会抛异常了。
解决问题
终于找到了问题的所在那么改如何解决呢 无法修改Spring AOP的逻辑但是可以控制Rhino的逻辑只需要把Rhino的Processor移到Spring AOP的Processor之后这样就可以在Rhino的Proccessor中处理经过Spring AOP的代理过的beanClass对象了有效的避免这个问题。
如何有效调整Processor的处理顺序 通过分析发现Spring AOP的内部实现基于Ordered接口而Rhino的实现是基于 PriorityOrdered接口而且处理器在初始化完成后会进行排序实现 PriorityOrdered接口的会放到前面相同类型的再根据设置的order进行排序。很显然Rhino的Processor被放在前面找到了问题解决方法也很简单Rhino也换成Order接口并且order设置成 LOWEST_PRECEDENCE即排在最后面。
结论
经过上面的调整之前这个问题确实被有效的解决了以前遇到Spring的异常都是一脸懵逼。所以遇到类似的问题最好通过DEBUG源码去发现问题并解决问题这样可以有效的防止后续的继续挖坑。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/91795.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!