如何在动态时间内使用不同的参数创建bean

时间:2019-07-11 09:20:11

标签: java spring

如果我有这样的课程:

@Service
@Scope("prototype")
public class TraderStarter {
private String address;
}

和TraderStarter应该创建X次,X由数据库动态确定。我应该如何获得这些豆子? 只有这样吗?

@Component("SpringContextUtil")
public class SpringContextUtil implements ApplicationContextAware {
    private  static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtil.applicationContext = applicationContext;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {
        return (T) applicationContext.getBean(name);
    }
}

使用SpringContextUtil .getBean()并为每个原型TraderStarter设置参数? 非常感谢。

1 个答案:

答案 0 :(得分:1)

简而言之,原型意味着在每次对此bean的请求时都会创建新bean(注入到不同的类/ getBean调用中)。

因此,如果您想创建这些原型bean,则有人会触发此过程。

当然,一种方法是使用ApplicationContext,但是IMO是一种不好的方法,因为您的代码已与spring耦合。

您不能将原型注入到单例中,这是行不通的。 但是,您可以使用与Spring集成的javax.inject.Provider接口:

这里是一个例子:

// from your example
// you can use injection here and everything, its a regular spring bean
@Service 
@Scope("prototype")
public class TraderStarter {
  private String address;

  public void setAddress(String address) {
      this.address = address;
  }   
}   

///////////////////////
@Component 
public class MyDbManager {

    private Provider<TraderStarter> traderStarterProvider; 

    public List<TraderStarter> dynamicallyCreateBeans() {
           List<String> addresses = dbManager.findAllAddresses();// to to the db, get the data
           return 
                addresses.stream()
                .map(this::createTraderStarter)  // <-- creates different beans! 

                .collect(Collectors.toList());
    }

    private TraderStarter createTraderStarter(String address) {
        TraderStarter ts = provider.get();
        ts.setAddress(address);
        return ts;
    }    
}

工厂还有其他方法(请参阅ObjectFactory)和创建代理(查找方法和作用域代理),但是IMO这是最干净的方法。

无论如何,如果您选择其他解决方案,请阅读this tutorial