最近在优化一个老系统,这是一个对外提供的dubbo服务,对响应时间要求很高,目前遇到的问题是到业务高峰时段,会有部分响应超时的情况出现。
既然要优化,第一步是得分析分析时间都消耗在哪里了,于是想在服务内的方法上加切面,使用spring的stopwatch来统计每次请求中每个方法执行的时间。写好了注解和切面,把注解加到方法上,然后本地跑起来测试,启动是成功了,但是dubbo admin上查无此服务,这就尴尬了,为什么呢。
在dubbo AnnotationBean里打断点跟了下
Service service = bean.getClass().getAnnotation(Service.class); if (service != null) { ServiceBean<Object> serviceConfig = new ServiceBean<Object>(service); serviceConfig.setRef(bean); if (void.class.equals(service.interfaceClass()) && "".equals(service.interfaceName())) { if (bean.getClass().getInterfaces().length > 0) { serviceConfig.setInterface(bean.getClass().getInterfaces()[0]); } else { throw new IllegalStateException("Failed to export remote service class " + bean.getClass().getName() + ", cause: The @Service undefined interfaceClass or interfaceName, and the service class unimplemented any interfaces."); } }
发现这个时候bean.getClass()得到的是xxxFacadeImpl$$EnhancerBySpringCGLIB$$f77b0d54,getInterafaces得到的是[org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.cglib.proxy.Factory]。大概有些同学就疑惑了,为啥这取到的是动态代理类呢,还不是因为咱用了spring aop来搞切面,人就是用动态代理方式来实现的。。。
public void setInterface(String interfaceName) { this.interfaceName = interfaceName; if (id == null || id.length() == 0) { id = interfaceName; } } public void setInterface(Class<?> interfaceClass) { if (interfaceClass != null && !interfaceClass.isInterface()) { throw new IllegalStateException("The interface class " + interfaceClass + " is not a interface!"); } this.interfaceClass = interfaceClass; setInterface(interfaceClass == null ? (String) null : interfaceClass.getName()); }
setInterface之后,serviceConfig的interfaceName和interfaceClass都变成了org.springframework.aop.SpringProxy,export后url是
dubbo://10.0.75.1:11601/org.springframework.aop.SpringProxy?anyhost=true&dubbo=2.5.7&generic=false&interface=org.springframework.aop.SpringProxy&methods=*&pid=14592
莫名喜感哈哈。看代码之后只能把这个if 给绕过去,这样export的时候interfaceName是你指定的那个,也就是在service注解里要么设置interfaceClass,要么设置interfaceName。于是这个问题解决了,服务又在dubbo admin上出现啦。
试着调用了一下,然后看日志,发现我去,这日志怎么跟想象的不一样,少了很多,折腾了许久,在切面上加断点,发现有些加了注解的方法就是不生效,怎么办,搜索一下找找灵感吧,发现了一篇文章https://www.baeldung.com/spring-aop-vs-aspectj,这文章本来看着也觉得没什么意思,后来一不小心瞄到了一句话It’s also worth noting that in Spring AOP, aspects aren’t applied to the method called within the same class。啊啊啊啊啊,真是一语惊醒梦中人啊,让我想起了以前就有的一个印象,在使用spring框架的工程中,service里a方法调用b方法,如果b上加了事务注解而a没加,那么事务是不生效的。
当时只是记住了这个结论,但是没有了解为啥,现在想想,动态代理是类似
public class proxy(){ public void a(){ doSomething(); super.a(); doSometing(); }
所以通过调用a去调用b的时候,实际不是在代理类的对象里,而是在被代理类的对象里了,也就是切面被略过了,咋办,难道我要改写spring aop吗,算了吧,想了想还是直接用aspectj吧,正好刚刚看过了spring-aop-vs-aspectj不是吗哈哈。
相关推荐
Spring AOP代理详细介绍 前言: 一开始我对spring AOP还是属于一知半解的状态,这几天遇到一个问题,加上又查看了一些Spring相关知识,感觉对这个问题有了更深刻的认识。所以写下来分享一下。 我们知道,Spring支持...
面试必考之HashMap源码分析与实现 探索JVM底层奥秘ClassLoader源码分析与案例讲解 面试必备技能之Dubbo企业实战 ...互联网系统垂直架构之Session解决方案 分库分表之后分布式下如何...无处不在的Spring AOP事务及踩过的坑
Spring AOP事务管理是Java开发中的重要组成部分,它极大地简化了在分布式系统中对事务的处理。Spring通过AOP(面向切面编程)提供了一种声明式事务管理方式,允许开发者将事务规则与业务逻辑分离,提高了代码的...
8月31日-无处不在的Spring AOP事务及踩过的坑-张飞.mp4
微信小程序详细图文教程 泉州大白网络科技 目录 一.微信小程序申请 二....1.申请服务器 2.部署服务器 3.域名申请和配置 三....一....申请,并认证(未认证不能发布,认证需要300元,目前只支持企业认证)详细见官网说明。...
aop|[aop,正则,前置通知,后置通知,环绕通知](https://github.com/smltq/spring-boot-demo/blob/master/aop/HELP.md) data-redis|[lettuce,redis,session redis,YAML配置,连接池,对象存储]...
- **面向切面编程(AOP)**:通过Spring AOP理解横切关注点是如何被抽象出来并独立于业务逻辑的。 - **数据访问/集成**:学习如何使用Spring进行数据库操作,包括JDBC、ORM框架如Hibernate的集成。 - **MVC框架**:...
9. **AOP开发中的坑**: - 当一个类内部的方法调用另一个方法时,由于是直接调用,不会触发代理。解决办法是使用`ApplicationContextAware`或者`AOPContext`获取代理对象。 10. **判断Bean是否为AOP代理对象**: ...
Spring 是 Java 企业版(Java EE)应用程序的框架,提供了结构化的配置文件,实现了控制反转(IoC)和面向切面编程(AOP),支持表现层、业务逻辑层和持久层。Spring 的核心是 IoC 和 AOP,能够与主流的第三方框架...
在使用 Spring AOP 时,可能会出现类型转换错误。解决方法是,检查 AOP 配置文件,确保 advisor 和 aspect 的配置正确,并且确保目标对象的类型正确。 Spring 集成异步任务线程池 在使用 Spring 时,可能需要集成...
不定期更新与记录在springcloud开发中所遇到的坑以及解决方法 初始化添加 spring-cloud skywalking demo add mqtt suports add 微信小程序 suports mqtt kafka elk支持 20180809 更新 代码结构 新增git配置中心 新增...
此外,Spring5还提供了AOP(面向切面编程)支持,用于处理如日志、事务等横切关注点,使得代码更简洁。 对于源码编译,Spring5的官方源码可以从GitHub上获取,通常包含多个模块,如spring-framework、spring-web、...
春天引导演示 本项目示例基于spring ...每个示例都带有详细的介绍文档,作者在使用过程中踩过的坑,解决方案和参考资料,方便快速上手为你提供学习捷径,少绕弯路,提高开发效率。 有需要写关于spring boot,spring clo
包括aop,自定义注释解,springmvc,jpa + hibernate,springlistener,@预定定时任务,过滤器的简单实用,包括简单的登录权限验证,设备crud功能cloud模块没得说,主要是亲手建造一整套springcloud服务,包括常用的...
6. **AOP(面向切面编程)**:SSH整合常利用Spring的AOP特性进行日志记录、权限控制等。确保AOP配置正确,定义合适的切点和通知,以便在适当的地方插入额外的逻辑。 7. **异常处理**:Struts2和Spring都有自己的...
17. SpringBoot 优雅配置跨域多种方式及 Spring Security 跨域访问配置的坑 SpringBoot 提供了多种方式来实现跨域配置,包括使用 @CrossOrigin 注解、使用 CorsConfiguration_SOURCE bean 等。 18. SpringBoot ...
拦截器主要用于AOP(面向切面编程)场景,常见于Spring MVC框架中。拦截器的执行流程是在Controller方法调用前后,可以实现诸如权限验证、日志记录、事务管理等功能。与过滤器相比,拦截器更具有面向对象的特性,...
在实际学习过程中,你需要逐步理解每个框架的核心概念,例如Spring的IoC和AOP、Struts2的Action和Result、Hibernate的Session和Query。同时,通过阅读和分析源码,你将了解如何在项目中合理划分模块,以及如何处理...
4. 使用Spring的AOP(面向切面编程)进行事务管理,例如通过@Transactional注解来标记事务边界。 5. 编写Controller层的代码,处理HTTP请求,调用Service层进行业务逻辑。 6. 编写Service层,实现业务逻辑,通过@...