2017-06-13 23 views

回答

0

我已經找到一種方法來看到有關創建原型豆實際的圖片。 我使用免費VisualVM內存分析器。

採樣器標籤中,您可以看到創建的類的所有實例,包括singleton和prototype bean。

你會看到你自己的軟件包和類的名稱。在這種情況下:

  • 原型是我的原型豆一包。

  • singleton是與我的單身豆包。

  • newclasses是與我通過運算符創建類的包。

另外,垃圾收集後將清理內存,您將在這裏看到的結果。

enter image description here

1

你可以通過發佈和收聽應用程序事件來完成。

  1. 創建您自己的活動。
  2. 原型bean創建時發送事件。
  3. 創建計數ApplicationListener,並聆聽收入創建事件。

我這裏是 Spring – Publish and Listen Application Events

春不管理的原型bean的整個生命週期:容器初始化,配置,裝飾或者是裝配一個原型對象,將它交給客戶端,然後有對原型實例沒有進一步的瞭解。

簡單的變體:

public class PrototypeCreationEvent extends ApplicationEvent { 
    private String beanName; 

    public PrototypeCreationEvent(Object source , String beanName) { 
     super(source); 
     this.beanName = beanName; 
    } 

    public String getBeanName(){ 
     return beanName; 
    } 
} 

public class PrototypeCreationListener implements ApplicationListener<PrototypeCreationEvent> { 
    private ConcurrentMap<String,AtomicInteger> prototypeCreationStatistic = new ConcurrentHashMap<>(); 
    //or from guava AtomicLongMap prototypeCreationStatistic = AtomicLongMap.create(); 

    @Override 
    public void onApplicationEvent(PrototypeCreationEvent event) { 
     prototypeCreationStatistic.computeIfAbsent(event.getBeanName() , k->new AtomicInteger(0)).incrementAndGet(); 

     System.out.println(event); 
    } 

    public ConcurrentMap<String,AtomicInteger> getPrototypeCreationStatistic(){ 
     return prototypeCreationStatistic; 
    } 
} 

public abstract class PrototypeCreationPublisher implements BeanNameAware , ApplicationEventPublisherAware ,InitializingBean { 
    private String beanName; 
    private ApplicationEventPublisher applicationEventPublisher; 


    @Override 
    public void setBeanName(String name) { 
     this.beanName = name; 
    } 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     System.out.println(); 
    } 

    @Override 
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { 
     this.applicationEventPublisher = applicationEventPublisher; 
    } 

    @PostConstruct //or use interface InitializingBean 
    public void sendEventAfterCreation() throws Exception { 
     applicationEventPublisher.publishEvent(new PrototypeCreationEvent(this , beanName)); 
    } 
} 

@Component(value = BeanDefinition.SCOPE_PROTOTYPE) 
public class PrototypeA extends PrototypeCreationPublisher{ 
} 

@Component(value = BeanDefinition.SCOPE_PROTOTYPE) 
public class PrototypeB extends PrototypeCreationPublisher{ 
} 

例如:

PrototypeA prototypeA1 = context.getBean(PrototypeA.class); 
    PrototypeA prototypeA2 = context.getBean(PrototypeA.class); 
    PrototypeA prototypeA3 = context.getBean(PrototypeA.class); 
    PrototypeB prototypeB1 = context.getBean(PrototypeB.class); 

    PrototypeCreationListener statistic = context.getBean(PrototypeCreationListener.class); 
    statistic.getPrototypeCreationStatistic().entrySet().forEach(s->{ 
     System.out.println(s.getKey() + " count = "+s.getValue()); 
    }); 

結果:

PrototypeB count = 1 
    PrototypeA count = 3 
+0

謝謝。有什麼辦法從ApplicationContext獲取信息嗎? –

+0

好的。我會盡力。 –

+0

可能是我不明白的東西......但我可以通過僅從bean的構造函數打印控制檯中的信息來獲取有關創建bean的信息。請看我更正的問題。在我們的項目中,我們有400多個原型bean,所以我想檢查一下原型bean的創建和數量。 –

相關問題