从命令行创建带参数的bean的惯用方法?

时间:2015-02-05 18:58:08

标签: java spring javabeans

例如,在我的spring应用程序中,我需要几个DBWorker Beans:

    @Component
    @Scope("prototype")
    class DBWorker {

    @Autowired
    JdbcTemplate templ;

    @Autowired
    SomeOtherDependency dep;


    public void init() {
        // use jdbcTemplate to pull some 
        // set up info from DB

   }

   public void run() {
    // pull maxNumberOfRows and print out
   }


    private int maxNumberOfRowsToPull;

    public void setMaxNumberOfRowsToPull() { .... }

    }

所以基本上我有一个类DBWorker,它需要一堆依赖项,比如jdbctemplate。让Spring注入这些依赖项很方便,所以我将这些依赖项标记为@Autowired。在我的应用程序中,我在不同的地方需要3个DBWorkers,它们对jdbcTemplate和SomeOtherDependency都有相同的依赖关系。但是每个都有不同的maxNumberOfRowsToPull,它们都是由命令行args设置的。

我需要在DBWorker上执行的逻辑步骤是: 实例化3名工人 在每个worker上调用init() 在每个工作人员上调用run()

因为maxNumberOfRowsToPull来自命令行(未修复),我无法将其放在spring config.xml中或使用@Value注释,即使我可以在配置中使用$ {system.property.name} ,对于3个工作人员来说这是不同的,我必须设置3次系统属性以间接地来到setMaxNumberOfRowsToPull(),这是丑陋的。 所以我必须直接调用setMaxNumberOfRowsToPull()。然后在我称呼之前,"状态"工作者是不完整的,所以在我明确调用setMaxNumberOfRowsToPull()之后我才能调用init(),所以我不能将init()逻辑放在构造函数中,并且必须调用init( )明确地说。另一方面,我想自动装配依赖项,所以我必须通过spring创建worker(否则不会注入依赖项)。总的来说,我现在拥有的最佳代码是:

DBWorker worker1 = (DBWorker) context.getBean(DBWorker.class);
// now the dependencies are already injected
worker1.setMaxNumberOfRowsToPull(args[0]);
worker1.setSomeOtherProperty(args[1]);
worker1.init();
worker1.run();

// then similar sequence for worker2 etc.

丑陋的部分是,如果我从命令行设置更多属性,我会有更多的调用,如setMaxNumberOfRowsToPull(),并且大多数工作者共享相同的参数,只有少数需要显式更改。所以我将这些属性的@Value设置为系统属性,让Spring处理它。因此,每个工作bean都会从Spring中出现一些"默认"属性设置,由命令行给出,我将不得不显式调用几个属性设置来更改默认值。这听起来有点可疑,因为创作后的几个豆子都在错误的#34;州。在概念上,我宁愿让每个bean在创建时都是正确的。

我也必须手动调用这个init(),因为我必须等待属性设置的手动调用。据说init()应该是spring bean initialization()的一部分,我不应该为每个dbworker做这个机械步骤。

理想情况下,我希望像

一样更清洁
DBWorker worker1 = context.getBean(DBWorker.class, args[0], args[1]);
// here the init() has been run inside constructor or in bean initialization()
worker1.run();
// then repeat above for worker2, worker3 ...

我想知道为这样的场景组织代码的惯用和干净方法是什么。 谢谢!

1 个答案:

答案 0 :(得分:1)

为什么不把变量放在init?

 public void init(String numberOfRowsToPull, String otherProp) {
        // use jdbcTemplate to pull some 
        // set up info from DB
        this.numberOfRowsToPull = numberOfRowsToPull;
        this.otherProp = otherProp;
   }

主要:

DBWorker worker1 = context.getBean(DBWorker.class);
worker1.init(args[0], args[1]);
worket1.run();

这是标准,我在很多地方遇到过这种情况,如果你想改变默认值,它的作用与构造函数相同。

希望有所帮助

编辑:

BeanFactorygetBean(String name, Object... args)

我没有尝试,但这应该为你做的工作..

getBean("dBWorker", args[0], args[1]);