Java多例Bean的应用场景-easyExcel导入

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

目录


在这里插入图片描述

1. bean注入方式IOC

在这里插入图片描述

2. 有状态会话bean和无状态会话bean

有状态会话bean每个用户有自己特有的一个实例在用户的生存期内bean保持了用户的信息即“有状态”一旦用户灭亡调用结束或实例结束bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。

无状态会话beanbean一旦实例化就被加进会话池中各个用户都可以共用。即使用户已经消亡bean 的生命期也不一定结束它可能依然存在于会话池中供其他用户调用。由于没有特定的用户那么也就不能保持某一用户的状态所以叫无状态bean。但无状态会话bean 并非没有状态如果它有自己的属性变量那么这些变量就会受到所有调用它的用户的影响这是在实际应用中必须注意的。
面试题单例 Bean 存在线程安全问题吗
答在 Bean 中尽量避免定义可变的成员变量。推荐的做法时在类中定义一个 ThreadLocal 成员变量将需要的可变成员变量保存在 ThreadLocal 中。
不过大部分 Bean 实际都是无状态没有实例变量的比如 Dao、Service这种情况下 Bean 是线程安全的。

3. 单例模式和多例模式

@Scope注解主要作用是调节Ioc容器中的作用域在Spring IoC容器中主要有以下几种作用域
基本作用域singleton单例、prototype(多例)
Web 作用域reqeust、session、globalsession
自定义作用域。
目前有90%以上的业务系统都使用singleton单实例因此spring也默认的类型也是singletonsingleton保证了全局是一个实例对性能有所提高但是如果实例中有非静态变量时可能会导致线程安全、共享资源的竞争等问题。
当设置为prototype多实例时每次连接请求都会重新生成一个新的bean实例这也会导致一个问题当请求数越多性能会降低因为频繁创建的新的实例会导致GC频繁GC回收时长增加。要根据实际情况选择哪一种方式。

4. 深挖多例模式应用场景

在Spring中prototype原型模式多例模式使用的场景不多只有当你的bean的属性中会有数据存在的时候才需要使用原型模式否则数据就串了。我自己使用过的一个场景是用EasyExcel实现导入功能的时候会使用到。
在使用EasyExcel读取表格文件时官方文档推荐的是自己进行new一个Listener对象但是想在这个对象中使用其他service对象的话就不能使用@Autowired了因为这个Listener对象并不受容器管理。其中Listener对象中用到的其他service或者DAO类通过构造方法初始化进去如果直接用@Autowired注入会报空指针错误项目中代码如下
Controller代码
在这里插入图片描述
Listener代码
在这里插入图片描述

我们可以考虑将这个Listener对象变成多例模式加上@Component和@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)两个注解
在这里插入图片描述
然后在Controller里面通过Spring容器获取这个对象注意一定要通过容器手动获取prototype原型模式的bean如果还通过@Autowired的形式注入的话这个对象还是同一个因为@Autowired只会注入一次

调用方通过Spring注入的方式自动注入EmployeeHouseImportListener而非new的方式这样获取到的EmployeeHouseImportListener是被Spring容器管理的进而可以在EmployeeHouseImportListener中通过@Autowired的方式成功获取到同样被Spring容器管理的UserService因为UserService 的实现类中有"@Service"注解标记。

//调用方
EmployeeHouseImportListener importListener = SpringUtils.getBean("employeeHouseImportListener");
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java