ryantenney / metrics-spring

Spring integration for Metrics
http://www.ryantenney.com/metrics-spring/
Apache License 2.0
702 stars 227 forks source link

Annotation on complex @Serivice don not work #125

Open hengyunabc opened 9 years ago

hengyunabc commented 9 years ago

Under the same package , I created some Service classes. I found that on some complex Service classes, metrics annotation do not work.

I found that, when spring construct the complex Service classes, the BeanPostProcessors:

[org.springframework.context.support.ApplicationContextAwareProcessor@1161a0d7, org.springframework.web.context.support.ServletContextAwareProcessor@56c5a05f, org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker@4c4e34b5, org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@74d80144, org.springframework.context.annotation.ConfigurationClassPostProcessor$EnhancedConfigurationBeanPostProcessor@68236010, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@131ff213, org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@2ec99759, org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor@1a2f71e5, org.apache.shiro.spring.LifecycleBeanPostProcessor@697fa150]

When spring constuct the simple Service classes, the BeanPostProcessors:

[org.springframework.context.support.ApplicationContextAwareProcessor@7cde6c6b, org.springframework.web.context.support.ServletContextAwareProcessor@2d3c4e79, org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker@6fd4df09, org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@75dc129, org.springframework.context.annotation.ConfigurationClassPostProcessor$EnhancedConfigurationBeanPostProcessor@8ef489d, org.apache.shiro.spring.LifecycleBeanPostProcessor@47ef807f, proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false, com.ryantenney.metrics.spring.MetricAnnotationBeanPostProcessor@e0a331c, com.ryantenney.metrics.spring.GaugeFieldAnnotationBeanPostProcessor@67b7ff7d, com.ryantenney.metrics.spring.GaugeMethodAnnotationBeanPostProcessor@156ef8b6, com.ryantenney.metrics.spring.CachedGaugeAnnotationBeanPostProcessor@2eb96e1c, com.ryantenney.metrics.spring.HealthCheckBeanPostProcessor@71f42a04, org.apache.shiro.spring.web.ShiroFilterFactoryBean@29606f50, com.ryantenney.metrics.spring.AdvisingBeanPostProcessor@4ba98982, com.ryantenney.metrics.spring.AdvisingBeanPostProcessor@2e85c765, com.ryantenney.metrics.spring.AdvisingBeanPostProcessor@7e717cbb, com.ryantenney.metrics.spring.AdvisingBeanPostProcessor@544196ca, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@53a3f059, org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@539dbba7, org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor@267c81cb, org.springframework.context.support.PostProcessorRegistrationDelegate$ApplicationListenerDetector@7e53b408]

I have yet to find the specific reason.

ryantenney commented 9 years ago

I'm sorry, I don't understand the issue. Can you provide more information?

hengyunabc commented 9 years ago

There are two @Service class: AService, BService.

@Service
public class AService {
  @Timed
  public void aaa(){
    System.err.println("aaa");
  }
@Service
public class BService {
  @Timed
  public void bbb(){
    System.err.println("bbb");
  }

They both work fine.

If I use AService in other spring bean, like:

@Service
public class CService {
  @Autowired
  AService aService;
}

The @Timed annotation in AService do not work! In my project, CService is complex, not like the above example.

I found that, when spring create AService, beanPostProcessors do not contains com.ryantenney.metrics.spring.AdvisingBeanPostProcessor

org.springframework.beans.factory.support.AbstractBeanFactory
    /** BeanPostProcessors to apply in createBean */
    private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();

beanPostProcessors only have these BeanPostProcessor.

com.ryantenney.metrics.spring.GaugeFieldAnnotationBeanPostProcessor@30162afc, 
com.ryantenney.metrics.spring.GaugeMethodAnnotationBeanPostProcessor@45d3ce31, 
com.ryantenney.metrics.spring.CachedGaugeAnnotationBeanPostProcessor@7e6ffca9, 
com.ryantenney.metrics.spring.MetricAnnotationBeanPostProcessor@310cae79, 
com.ryantenney.metrics.spring.HealthCheckBeanPostProcessor@304c336e

When spring create BService, beanPostProcessors has 4 AdvisingBeanPostProcessor.

com.ryantenney.metrics.spring.GaugeFieldAnnotationBeanPostProcessor@30162afc, 
com.ryantenney.metrics.spring.GaugeMethodAnnotationBeanPostProcessor@45d3ce31, 
com.ryantenney.metrics.spring.CachedGaugeAnnotationBeanPostProcessor@7e6ffca9, 
com.ryantenney.metrics.spring.MetricAnnotationBeanPostProcessor@310cae79, 
com.ryantenney.metrics.spring.HealthCheckBeanPostProcessor@304c336e, 
com.ryantenney.metrics.spring.AdvisingBeanPostProcessor@69263d6a, 
com.ryantenney.metrics.spring.AdvisingBeanPostProcessor@6aa128ea, 
com.ryantenney.metrics.spring.AdvisingBeanPostProcessor@6fa093db, 
com.ryantenney.metrics.spring.AdvisingBeanPostProcessor@603cb48f, 
org.apache.shiro.spring.web.ShiroFilterFactoryBean@38a9088f,
hengyunabc commented 9 years ago

I try to use Ordered.

class AdvisingBeanPostProcessor implements BeanPostProcessor ,Ordered {
  ...
  @Override
  public int getOrder() {
    return LOWEST_PRECEDENCE;
  }

When spring create AService, beanPostProcessors contains AdvisingBeanPostProcessor, but it cause exception:

its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.
ryantenney commented 9 years ago

You shouldn't be dealing directly with BeanPostProcessors…

hengyunabc commented 9 years ago

I have not dealing directly with BeanPostProcessors. I just debug and try to find out the reason.

I mean that when spring create AService,the spring context has not add AdvisingBeanPostProcessor into beanPostProcessors, so @Timed annotation in AService do not work.

When spring create BService, the spring context already add AdvisingBeanPostProcessor into beanPostProcessors, so @Timed annotation in BService works.

I don not know why.

Forgive my poor english, I hope that you can understand what I mean.

purecharger commented 7 years ago

I believe I have the same issues, preventing upgrade to anything past 3.1.0. The changes related to deprecating com.ryantenney annotations in favor of com.codahale, along with the associated bean processors, seem to be likely culprits: https://github.com/ryantenney/metrics-spring/commit/577b35bc30b3b7dfc2170b8398b69bad8d181424