spring自动创建代理类DefaultAdvisorAutoProxyCreator和BeanNameAutoProxyCreator的声明顺序

最近做项目,在接入flume监控(开源的分布式监控系统)时,发现监控异常,通过排查发现是spring创建代理类DefaultAdvisorAutoProxyCreator和BeanNameAutoProxyCreator的声明顺序不对导致,下面介绍一下问题和解决过程:


1、异常描述:

1.1、异常简述:服务有10台机器,2台机器flume监控正常,8台机器flume有部分方法无法监控。

1.2、异常详情:

(1)服务接入flume监控,上线后发现有8台机器flume监控不完全,漏掉2个方法没有打印监控log。

(2)线上代码和各种配置都统一,也找了维护flume的同学看了下,没有看出flume有异常。

(3)重启服务,情况无变化,正常的2台还是正常,异常的8台还是异常。

(4)测试环境正常。


2、问题排查:

2.1、发现去掉flume监控log,只配本地log,仍然存在此异常。因此怀疑是代理的配置引起的问题。

2.2、flume的代理是DefaultAdvisorAutoProxyCreator,工程中存在另外一个BeanNameAutoProxyCreator代理,用来监控接口耗时。

2.3、这两个代理拦截了一个相同的bean:clearService,flume没有打印监控log的两个方法正好都属于这个bean。

<bean id= "clearService"  class = "com.meituan.pay.clear.service.impl.ClearServiceImpl" />

2.4、检查10台线上机器加载这两个代理的顺序,flume正常的机器加载顺序为DefaultAdvisorAutoProxyCreator、BeanNameAutoProxyCreator,异常机器均为BeanNameAutoProxyCreator、DefaultAdvisorAutoProxyCreator。

2.5、在BeanNameAutoProxyCreator声明中加入属性 depends-on=“DefaultAdvisorAutoProxyCreator”,保证DefaultAdvisorAutoProxyCreator代理先实例化。重启服务,发现DefaultAdvisorAutoProxyCreator确实优先实例化,但是flume监控依然异常。怀疑不是实例化顺序的问题。(BeanNameAutoProxyCreator的声明放在DefaultAdvisorAutoProxyCreator前面)


3、解决问题:

     保证先加载DefaultAdvisorAutoProxyCreator,再加载BeanNameAutoProxyCreator

3.1、查看源码,发现DefaultAdvisorAutoProxyCreator和BeanNameAutoProxyCreator两个代理都实现了Ordered接口,order值越小执行优先级越高,于是尝试在代理配置中注入order属性。重启服务,flume监控正常。


4、原理、概念介绍:

4.1、depends-on属性:保证当前bean在所依赖的bean初始化之后才初始化。 

<!-- advisorAutoProxyCreator优先于accessLogAutoProxyCreator初始化 -->
<bean id= "accessLogAutoProxyCreator"  class = "org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"  depends-on= "advisorAutoProxyCreator" >

4.2、BeanPostProcessor接口:在Spring容器完成Bean的初始化前后,添加一些自己的逻辑处理,我们就可以定义一个或者多个BeanPostProcessor接口的实现。比如当Spring容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的Bean,并注入到对应的地方中去。

public  interface  BeanPostProcessor {
     Object postProcessBeforeInitialization(Object bean, String beanName)  throws  BeansException;
     Object postProcessAfterInitialization(Object bean, String beanName)  throws  BeansException;
}  

4.3、DefaultAdvisorAutoProxyCreator类:

(1)自动创建代理的类,它会 cahce 容器中所有注册的 advisor, 然后搜索容器中所有的 bean , 如果某个 bean 满足 advisor 中的 Pointcut, 那么将会被自动代理。

(2)实现了BeanPostProcessor和Ordered接口。

(3)它会根据bean的类型判断该bean是否匹配。

<!-- 定义一个切面,advice定义拦截行为,patterns定义匹配的拦截目标集合 -->
<bean id= "regexpMethodPointcutAdvisor"  class = "org.springframework.aop.support.RegexpMethodPointcutAdvisor" >
     <property name= "advice"  ref= "methodMonitorInterceptor" />
     <property name=
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值