Spring 应用程序中特定 Prototype-bean 的已创建实体数?

Count of already created entities of particular Prototype-bean in Spring application?

有什么方法可以获取应用程序中特定原型 bean 的已创建实体的数量和一些标识信息

加法。在我们的项目中,我们有超过 400 个原型 beans,我想跟踪在执行期间创建的 beans 的状态以及每种类型的实体数量。

您可以通过发布和监听应用程序事件来完成。

  1. 创建您自己的活动。
  2. 创建原型 bean 时从中发送事件。
  3. 创建count个ApplicationListener,并监听income创建事件。

这是例子 Spring – Publish and Listen Application Events

Spring 不管理原型 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

我找到了一种方法来查看有关创建的原型 bean 的实际情况。 我使用免费的 VisualVM 内存分析器。

Sampler 选项卡中,您可以看到创建的 类 的所有实例,包括单例和原型 bean。

您将看到您自己的包的名称和 类。在这种情况下:

  • prototype 是一个包含我的原型 bean 的包。

  • singleton 是一个包含我的 singleton-beans 的包。

  • new类 是由 new 创建的包含 类 的包运算符.

此外,在 垃圾收集器 将清理内存后,您将在此处看到结果。