Spring中bean指定prototype原型模式写法及使用场景

在Spring中,默认bean对象都是单例的,也就是通过getBean方法或者@Autowired注解获取到的bean对象都是同一个。我们可以通过@Scope注解来修改bean的模式为原型模式,这样每一次从Spring容器中获取到的bean对象就都是新的了。

通过@Scope注解及prototype参数即可修改bean为原型模式

@Component
@Scope("prototype")

为了避免prototype写错(毕竟没有提示,不过写错的时候启动会报错也无碍),建议使用ConfigurableBeanFactory接口中的常量

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

在Spring中,prototype原型模式使用的场景不多,只有当你的bean的属性中会有数据存在的时候,才需要使用原型模式,否则数据就串了不是。我自己使用过的一个场景是用EasyExcel实现导入功能的时候会使用到。

https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read

在使用EasyExcel读取表格文件时,官方文档推荐的是自己进行new一个Listener对象,但是想在这个对象中使用其他service对象的话,就不能使用@Autowired了,不方便,所以我们可以考虑将这个Listener对象变成原型模式:

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DemoDataListener extends AnalysisEventListener<DemoData> {

    /**
     * 表格中的数据
     */
    private List<DemoData> dataList = new ArrayList<>();

    @Autowired
    private DemoService demoService;

    @Override
    public void invoke(DemoData data, AnalysisContext context) {
        dataList.add(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        demoService.save(dataList);
    }

}

然后在Controller里面通过Spring容器获取这个对象(注意:一定要通过容器手动获取,prototype原型模式的bean如果还通过@Autowired的形式注入的话,这个对象还是同一个,因为@Autowired只会注入一次)

DemoDataListener listener = SpringUtil.getApplicationContext().getBean(DemoDataListener.class);

获取Spring容器的部分可以参考:Spring获取上下文对象ApplicationContext的2种办法


觉得内容还不错?打赏个钢镚鼓励鼓励!!👍