首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用运行时参数创建一个原型作用域的@Bean?With getBean(字符串名,对象...args)?

如何使用运行时参数创建一个原型作用域的@Bean?With getBean(字符串名,对象...args)?
EN

Stack Overflow用户
提问于 2018-05-26 05:00:00
回答 3查看 279关注 0票数 1

如何使用运行时参数创建一个原型作用域的@Bean?和getBean(String name, Object... args)?我的问题是.的结果

为什么在 中没有使用或提到此方法

这是一个正常的方法吗?有没有更正确的方法来创建一个带有运行时参数的原型@Bean?

如果这是而不是 normal方法,那么你能解释一下为什么吗?注意,我需要通过构造函数来设置参数,而不是通过来设置。

代码语言:javascript
复制
@Autowired
private ApplicationContext appCtx;

public void onRequest(Request request) {
    //request is already validated
    String name = request.getParameter("name");
    Thing thing = appCtx.getBean(Thing.class, name);

    //System.out.println(thing.getName()); //prints name
}

-

代码语言:javascript
复制
public class Thing {

    private final String name;

    @Autowired
    private SomeComponent someComponent;

    @Autowired
    private AnotherComponent anotherComponent;

    public Thing(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}
EN

回答 3

Stack Overflow用户

发布于 2018-05-26 05:10:21

在构造函数注入方面,没有。但是,您可以为Thing提供init方法并使用ObjectFactory

代码语言:javascript
复制
@Autowired
private ObjectFactory<Thing> thingFactory;

public void onRequest(Request request) {
    //request is already validated
    Thing thing = thingFactory.getObject();
    thing.init("name");

    //System.out.println(thing.getName()); //prints name
}

事情是:

代码语言:javascript
复制
@Component
@Scope("prototype")
public class Thing {

    private String name;

    @Autowired
    private SomeComponent someComponent;

    @Autowired
    private AnotherComponent anotherComponent;

    public init(String name) {
        this.name = name;
    }

}

不幸的是,name不能是final,因为它不是通过构造函数实现的。我很想看看是否有更好的方法来使用constructor injection实现这一点。

票数 0
EN

Stack Overflow用户

发布于 2018-05-28 19:37:24

在bean工厂的帮助下,这是可能的:

代码语言:javascript
复制
@Configuration
public class ThingProvider {

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Thing create(String name) {
        return new Thing(name);
    }

}

用法:

代码语言:javascript
复制
@Component
public class SomeBean {

    @Autowired
    private ThingProvider thingProvider;

    public void onRequest(Request request) {

        String name = request.getParameter("name");
        Thing thing = myProvider.create(name);
    }

}

经常有人提出反对appCtx.getBean(Thing.class, name)的理由是,它需要硬连接特定于Spring的类。另外,没有编译时检查,以防Thing构造函数发生更改。

票数 0
EN

Stack Overflow用户

发布于 2021-11-09 16:01:32

在这种情况下,您的Thing类可能会混合使用构造函数依赖关系和运行时参数,如下所示:

代码语言:javascript
复制
public class Thing {

    private final SomeComponent someComponent;
    private final AnotherComponent anotherComponent;

    private final String name;

    @Autowired
    public Thing(SomeComponent someComponent,
                 AnotherComponent anotherComponent,
                 String name) {
        this.someComponent = someComponent;
        this.anotherComponent = anotherComponent;
        this.name = name;
    }

    public String getName() {
        return this.name;
    } 
}

然后,您可以将它们包装在配置中:

代码语言:javascript
复制
@Configuration
public class BeanConfig {

    @Autowired
    private SomeComponent someComponent;

    @Autowired
    private final AnotherComponent anotherComponent;

    @Bean
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    public Thing createThing(String name) {
        return new Thing(someComponent, anotherComponent, name);
    }
}

用法:

代码语言:javascript
复制
@Autowired
private BeanFactory beanFactory;

public void onRequest(Request request) {
    String name = request.getParameter("name");
    Thing thing = beanFactory.getBean(Thing.class, name);
}

它应该是有效的,但不确定这是否是一个好的实践。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50536771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档