You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中ObjectFactory创建原型Bean的性能优化问询

解答

测试结果符合预期

纯new操作只是直接调用构造器,无额外逻辑;而Spring的ObjectFactory.getObject()创建原型Bean时,会执行完整的容器管理流程:

  • 查找Bean定义
  • 实例化依赖的原型Bean(Car、Clothes)
  • 处理@Autowired依赖注入
  • 执行生命周期回调(如@PostConstruct)
  • 生成AOP代理(若有切面)
    这些步骤会带来显著性能开销,因此两者的耗时差异是正常现象。

高效创建原型Bean的优化方案

1. 自定义工厂类,减少Spring容器重复处理

若需保留Spring对依赖的管理,可自定义工厂类手动实例化主Bean,仅让Spring管理依赖创建:

@Component
public class EmployeeFactory {
    @Autowired
    private ObjectFactory<Car> carFactory;
    @Autowired
    private ObjectFactory<Clothes> clothesFactory;

    public Employee createEmployee() {
        // 直接调用构造器创建Employee,依赖由Spring提供
        return new Employee(carFactory.getObject(), clothesFactory.getObject());
    }
}

使用时注入EmployeeFactory并调用createEmployee(),跳过Spring对Employee的完整Bean创建流程,性能会比直接用ObjectFactory<Employee>.getObject()提升数倍。

2. 预获取构造器,完全绕过Spring容器流程

若原型Bean不需要Spring的生命周期回调、AOP等特性,可直接获取构造器手动创建所有对象,性能接近纯new:

@Autowired
private BeanFactory beanFactory;

// 预加载构造器,放在初始化方法中
private Constructor<Employee> employeeConstructor;
private Constructor<Car> carConstructor;
private Constructor<Clothes> clothesConstructor;

@PostConstruct
public void initConstructors() throws NoSuchMethodException {
    employeeConstructor = Employee.class.getConstructor(Car.class, Clothes.class);
    carConstructor = Car.class.getConstructor();
    clothesConstructor = Clothes.class.getConstructor();
}

public void start() {
    var startTime = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
        try {
            Car car = carConstructor.newInstance();
            Clothes clothes = clothesConstructor.newInstance();
            Employee employee = employeeConstructor.newInstance(car, clothes);
            employee.goToWork();
            employees.add(employee);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    double totalTime = System.currentTimeMillis() - startTime;
    System.out.println("Optimized Spring seconds: " + totalTime/1000);
}

注意:这种方式完全脱离Spring容器管理,后续依赖关系变化需手动修改代码。

3. 调整依赖作用域(业务允许时)

若Car和Clothes不需要每次创建新实例,可将其作用域改为单例(默认就是单例),Spring仅创建一次Car和Clothes实例,每次创建Employee时直接注入这两个单例对象,能大幅降低ObjectFactory.getObject()的耗时。

4. 直接使用BeanFactory获取Bean

ObjectFactory本质是对BeanFactory的委托,直接注入BeanFactory并调用getBean(Employee.class),能减少一层代理开销,性能略优于ObjectFactory.getObject(),但提升幅度有限。


内容的提问来源于stack exchange,提问作者andresmonc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:35:19